/*
* 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 < http : //www.gnu.org/licenses/>.
*
* Authors : Matthias Clasen < mclasen @ redhat . com >
*/
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/* 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;
GBytes *source;
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_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_GL_UNIFORM_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_GL_UNIFORM_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_GL_UNIFORM_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_GL_UNIFORM_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_GL_UNIFORM_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_GL_UNIFORM_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_GL_UNIFORM_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_GL_UNIFORM_TYPE_VEC4);
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "progress" ), ==, 0 );
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "dots" ), ==, 1 );
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "center" ), ==, 2 );
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "test1" ), ==, 3 );
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "test2" ), ==, 4 );
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "test3" ), ==, 5 );
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "test4" ), ==, 6 );
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "test5" ), ==, 7 );
g_assert_cmpint (gsk_gl_shader_find_uniform_by_name (shader, "nosucharg" ), ==, -1 );
g_assert_cmpint (gsk_gl_shader_get_uniform_offset (shader, 0 ), ==, 0 );
g_assert_cmpint (gsk_gl_shader_get_uniform_offset (shader, 1 ), >, 0 );
g_assert_cmpint (gsk_gl_shader_get_uniform_offset (shader, 2 ), >, 0 );
g_assert_cmpint (gsk_gl_shader_get_uniform_offset (shader, 3 ), >, 0 );
g_assert_cmpint (gsk_gl_shader_get_uniform_offset (shader, 4 ), >, 0 );
g_assert_cmpint (gsk_gl_shader_get_uniform_offset (shader, 5 ), >, 0 );
g_assert_cmpint (gsk_gl_shader_get_uniform_offset (shader, 6 ), >, 0 );
g_assert_cmpint (gsk_gl_shader_get_uniform_offset (shader, 7 ), >, 0 );
g_assert_null (gsk_gl_shader_get_resource (shader));
g_object_get (shader, "source" , &source, NULL);
g_assert_true (g_bytes_equal (source, bytes));
g_object_unref (shader);
g_bytes_unref (bytes);
g_bytes_unref (source);
}
static void
test_create_data (void )
{
GBytes *bytes;
GBytes *bytes2;
GskGLShader *shader;
GskShaderArgsBuilder *builder;
GskShaderArgsBuilder *builder2;
graphene_vec2_t v2, vv2;
graphene_vec3_t v3, vv3;
graphene_vec4_t v4, vv4;
GskRenderNode *node;
GskRenderNode *children[2 ];
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_shader_args_builder_new (shader, NULL);
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_shader_args_builder_set_float (builder, 0 , 0 .5 );
gsk_shader_args_builder_set_float (builder, 1 , 20 .0 );
gsk_shader_args_builder_set_vec2 (builder, 2 , &v2);
gsk_shader_args_builder_set_int (builder, 3 , -99 );
gsk_shader_args_builder_set_uint (builder, 4 , 99 );
gsk_shader_args_builder_set_bool (builder, 5 , 1 );
gsk_shader_args_builder_set_vec3 (builder, 6 , &v3);
gsk_shader_args_builder_set_vec4 (builder, 7 , &v4);
bytes = gsk_shader_args_builder_to_args (builder);
g_assert_cmpfloat (gsk_gl_shader_get_arg_float (shader, bytes, 0 ), ==, 0 .5 );
g_assert_cmpfloat (gsk_gl_shader_get_arg_float (shader, bytes, 1 ), ==, 20 .0 );
gsk_gl_shader_get_arg_vec2 (shader, bytes, 2 , &vv2);
g_assert_true (graphene_vec2_equal (&v2, &vv2));
g_assert_cmpint (gsk_gl_shader_get_arg_int (shader, bytes, 3 ), ==, -99 );
g_assert_cmpuint (gsk_gl_shader_get_arg_uint (shader, bytes, 4 ), ==, 99 );
g_assert_cmpint (gsk_gl_shader_get_arg_bool (shader, bytes, 5 ), ==, 1 );
gsk_gl_shader_get_arg_vec3 (shader, bytes, 6 , &vv3);
g_assert_true (graphene_vec3_equal (&v3, &vv3));
gsk_gl_shader_get_arg_vec4 (shader, bytes, 7 , &vv4);
g_assert_true (graphene_vec4_equal (&v4, &vv4));
children[0 ] = gsk_color_node_new (&(GdkRGBA){0 ,0 ,0 ,1 }, &GRAPHENE_RECT_INIT (0 , 0 , 50 , 50 ));
children[1 ] = gsk_color_node_new (&(GdkRGBA){1 ,0 ,0 ,1 }, &GRAPHENE_RECT_INIT (0 , 0 , 50 , 50 ));
node = gsk_gl_shader_node_new (shader,
&GRAPHENE_RECT_INIT (0 , 0 , 50 , 50 ),
bytes,
children,
2 );
g_assert_true (gsk_gl_shader_node_get_shader (node) == shader);
g_assert_cmpuint (gsk_gl_shader_node_get_n_children (node), ==, 2 );
g_assert_true (gsk_gl_shader_node_get_child (node, 0 ) == children[0 ]);
g_assert_true (gsk_gl_shader_node_get_child (node, 1 ) == children[1 ]);
gsk_render_node_unref (children[0 ]);
gsk_render_node_unref (children[1 ]);
gsk_render_node_unref (node);
builder2 = gsk_shader_args_builder_new (shader, bytes);
gsk_shader_args_builder_ref (builder2);
bytes2 = gsk_shader_args_builder_free_to_args (builder2);
gsk_shader_args_builder_unref (builder2);
g_assert_true (g_bytes_equal (bytes, bytes2));
g_bytes_unref (bytes2);
g_bytes_unref (bytes);
gsk_shader_args_builder_unref (builder);
g_object_unref (shader);
}
static void
test_format_args (void )
{
GBytes *bytes;
GskGLShader *shader;
graphene_vec2_t v2, vv2;
graphene_vec3_t v3, vv3;
graphene_vec4_t v4, vv4;
float f1, f2;
GBytes *args;
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);
graphene_vec2_init (&v2, 20 , 30 );
graphene_vec3_init (&v3, -1 , -2 , -3 );
graphene_vec4_init (&v4, 100 , 0 , -100 , 10 );
f1 = 0 .5 ;
f2 = 20 .0 ;
args = gsk_gl_shader_format_args (shader,
"progress" , f1,
"dots" , f2,
"center" , &v2,
"test4" , &v3,
"test5" , &v4,
NULL);
g_assert_cmpfloat (gsk_gl_shader_get_arg_float (shader, args, 0 ), ==, 0 .5 );
g_assert_cmpfloat (gsk_gl_shader_get_arg_float (shader, args, 1 ), ==, 20 .0 );
gsk_gl_shader_get_arg_vec2 (shader, args, 2 , &vv2);
g_assert_true (graphene_vec2_equal (&v2, &vv2));
gsk_gl_shader_get_arg_vec3 (shader, args, 6 , &vv3);
g_assert_true (graphene_vec3_equal (&v3, &vv3));
gsk_gl_shader_get_arg_vec4 (shader, args, 7 , &vv4);
g_assert_true (graphene_vec4_equal (&v4, &vv4));
g_bytes_unref (args);
g_object_unref (shader);
}
static void
test_compile (void )
{
GBytes *bytes;
GskGLShader *shader;
GdkSurface *surface;
GskRenderer *renderer;
GError *error = NULL;
gboolean ret;
bytes = g_bytes_new_static ("blaat" , 6 );
shader = gsk_gl_shader_new_from_bytes (bytes);
g_assert_nonnull (shader);
surface = gdk_surface_new_toplevel (gdk_display_get_default ());
renderer = gsk_renderer_new_for_surface (surface);
g_assert_nonnull (renderer);
ret = gsk_gl_shader_compile (shader, renderer, &error);
g_assert_false (ret);
g_assert_nonnull (error);
if (g_str_equal (G_OBJECT_TYPE_NAME (renderer), "GskGLRenderer" ))
g_assert_nonnull (strstr (error->message, "blaat" ));
else
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
g_clear_error (&error);
gsk_renderer_unrealize (renderer);
g_object_unref (renderer);
gdk_surface_destroy (surface);
g_bytes_unref (bytes);
}
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);
g_test_add_func ("/shader/format-args" , test_format_args);
g_test_add_func ("/shader/compile" , test_compile);
return g_test_run ();
}
G_GNUC_END_IGNORE_DEPRECATIONS
Messung V0.5 in Prozent C=98 H=90 G=94
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland