From 9defc7fc6473da76112d21df6586d35d80d4bb4c Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 17 Mar 2022 16:50:51 -0700 Subject: [PATCH] gsk/gl: add more control over shader generation This allows the gskglprograms.defs a bit more control over how a shader will get generated and if it needs to combine sources. Currently, none of the built-in shaders do that, but upcoming shaders which come from external libraries will need the ability to inject additional sources in-between layers. --- gsk/gl/gskgldriver.c | 70 ++++++++++++++++++++++++++++++++++----- gsk/gl/gskglprograms.defs | 32 +++++++++--------- 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 5154aeabb2..0980eba0ae 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -229,6 +229,29 @@ gsk_gl_driver_shader_weak_cb (gpointer data, g_hash_table_remove (self->shader_cache, where_object_was); } +G_GNUC_NULL_TERMINATED static inline GBytes * +join_sources (GBytes *first_bytes, + ...) +{ + GByteArray *byte_array = g_byte_array_new (); + GBytes *bytes = first_bytes; + va_list args; + + va_start (args, first_bytes); + while (bytes != NULL) + { + gsize len; + const guint8 *data = g_bytes_get_data (bytes, &len); + if (len > 0) + g_byte_array_append (byte_array, data, len); + g_bytes_unref (bytes); + bytes = va_arg (args, GBytes *); + } + va_end (args); + + return g_byte_array_free_to_bytes (byte_array); +} + static void gsk_gl_driver_dispose (GObject *object) { @@ -238,6 +261,10 @@ gsk_gl_driver_dispose (GObject *object) g_assert (self->in_frame == FALSE); #define GSK_GL_NO_UNIFORMS +#define GSK_GL_SHADER_RESOURCE(name) +#define GSK_GL_SHADER_STRING(str) +#define GSK_GL_SHADER_SINGLE(name) +#define GSK_GL_SHADER_JOINED(kind, ...) #define GSK_GL_ADD_UNIFORM(pos, KEY, name) #define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \ GSK_GL_DELETE_PROGRAM(name); \ @@ -251,6 +278,10 @@ gsk_gl_driver_dispose (GObject *object) } G_STMT_END; # include "gskglprograms.defs" #undef GSK_GL_NO_UNIFORMS +#undef GSK_GL_SHADER_RESOURCE +#undef GSK_GL_SHADER_STRING +#undef GSK_GL_SHADER_SINGLE +#undef GSK_GL_SHADER_JOINED #undef GSK_GL_ADD_UNIFORM #undef GSK_GL_DEFINE_PROGRAM @@ -351,14 +382,14 @@ gsk_gl_driver_load_programs (GskGLDriver *self, /* Setup preambles that are shared by all shaders */ gsk_gl_compiler_set_preamble_from_resource (compiler, - GSK_GL_COMPILER_ALL, - "/org/gtk/libgsk/gl/preamble.glsl"); + GSK_GL_COMPILER_ALL, + "/org/gtk/libgsk/gl/preamble.glsl"); gsk_gl_compiler_set_preamble_from_resource (compiler, - GSK_GL_COMPILER_VERTEX, - "/org/gtk/libgsk/gl/preamble.vs.glsl"); + GSK_GL_COMPILER_VERTEX, + "/org/gtk/libgsk/gl/preamble.vs.glsl"); gsk_gl_compiler_set_preamble_from_resource (compiler, - GSK_GL_COMPILER_FRAGMENT, - "/org/gtk/libgsk/gl/preamble.fs.glsl"); + GSK_GL_COMPILER_FRAGMENT, + "/org/gtk/libgsk/gl/preamble.fs.glsl"); /* Setup attributes that are provided via VBO */ gsk_gl_compiler_bind_attribute (compiler, "aPosition", 0); @@ -368,10 +399,28 @@ gsk_gl_driver_load_programs (GskGLDriver *self, /* Use XMacros to register all of our programs and their uniforms */ #define GSK_GL_NO_UNIFORMS +#define GSK_GL_SHADER_RESOURCE(name) \ + g_bytes_ref(g_resources_lookup_data("/org/gtk/libgsk/gl/" name, 0, NULL)) +#define GSK_GL_SHADER_STRING(str) \ + g_bytes_new_static(str, strlen(str)) +#define GSK_GL_SHADER_SINGLE(bytes) \ + G_STMT_START { \ + GBytes *b = bytes; \ + gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_ALL, b); \ + g_bytes_unref (b); \ + } G_STMT_END; +#define GSK_GL_SHADER_JOINED(kind, ...) \ + G_STMT_START { \ + GBytes *bytes = join_sources(__VA_ARGS__); \ + gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_##kind, bytes); \ + g_bytes_unref (bytes); \ + } G_STMT_END; #define GSK_GL_ADD_UNIFORM(pos, KEY, name) \ gsk_gl_program_add_uniform (program, #name, UNIFORM_##KEY); -#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \ - gsk_gl_compiler_set_source_from_resource (compiler, GSK_GL_COMPILER_ALL, resource); \ +#define GSK_GL_DEFINE_PROGRAM(name, sources, uniforms) \ + gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_VERTEX, NULL); \ + gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_FRAGMENT, NULL); \ + sources \ GSK_GL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \ GSK_GL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \ GSK_GL_COMPILE_PROGRAM(name, uniforms, ""); @@ -404,6 +453,11 @@ gsk_gl_driver_load_programs (GskGLDriver *self, #undef GSK_GL_DEFINE_PROGRAM_CLIP #undef GSK_GL_DEFINE_PROGRAM #undef GSK_GL_ADD_UNIFORM +#undef GSK_GL_SHADER_SINGLE +#undef GSK_GL_SHADER_JOINED +#undef GSK_GL_SHADER_RESOURCE +#undef GSK_GL_SHADER_STRING +#undef GSK_GL_NO_UNIFORMS ret = TRUE; diff --git a/gsk/gl/gskglprograms.defs b/gsk/gl/gskglprograms.defs index a6d9515a78..1ff99fab89 100644 --- a/gsk/gl/gskglprograms.defs +++ b/gsk/gl/gskglprograms.defs @@ -1,71 +1,71 @@ GSK_GL_DEFINE_PROGRAM (blend, - "/org/gtk/libgsk/gl/blend.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blend.glsl")), GSK_GL_ADD_UNIFORM (1, BLEND_SOURCE2, u_source2) GSK_GL_ADD_UNIFORM (2, BLEND_MODE, u_mode)) GSK_GL_DEFINE_PROGRAM (blit, - "/org/gtk/libgsk/gl/blit.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blit.glsl")), GSK_GL_NO_UNIFORMS) GSK_GL_DEFINE_PROGRAM (blur, - "/org/gtk/libgsk/gl/blur.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blur.glsl")), GSK_GL_ADD_UNIFORM (1, BLUR_RADIUS, u_blur_radius) GSK_GL_ADD_UNIFORM (2, BLUR_SIZE, u_blur_size) GSK_GL_ADD_UNIFORM (3, BLUR_DIR, u_blur_dir)) GSK_GL_DEFINE_PROGRAM (border, - "/org/gtk/libgsk/gl/border.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("border.glsl")), GSK_GL_ADD_UNIFORM (1, BORDER_WIDTHS, u_widths) GSK_GL_ADD_UNIFORM (2, BORDER_OUTLINE_RECT, u_outline_rect)) GSK_GL_DEFINE_PROGRAM (color, - "/org/gtk/libgsk/gl/color.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("color.glsl")), GSK_GL_NO_UNIFORMS) GSK_GL_DEFINE_PROGRAM (coloring, - "/org/gtk/libgsk/gl/coloring.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("coloring.glsl")), GSK_GL_NO_UNIFORMS) GSK_GL_DEFINE_PROGRAM (color_matrix, - "/org/gtk/libgsk/gl/color_matrix.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("color_matrix.glsl")), GSK_GL_ADD_UNIFORM (1, COLOR_MATRIX_COLOR_MATRIX, u_color_matrix) GSK_GL_ADD_UNIFORM (2, COLOR_MATRIX_COLOR_OFFSET, u_color_offset)) GSK_GL_DEFINE_PROGRAM (conic_gradient, - "/org/gtk/libgsk/gl/conic_gradient.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("conic_gradient.glsl")), GSK_GL_ADD_UNIFORM (1, CONIC_GRADIENT_COLOR_STOPS, u_color_stops) GSK_GL_ADD_UNIFORM (2, CONIC_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops) GSK_GL_ADD_UNIFORM (3, CONIC_GRADIENT_GEOMETRY, u_geometry)) GSK_GL_DEFINE_PROGRAM (cross_fade, - "/org/gtk/libgsk/gl/cross_fade.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("cross_fade.glsl")), GSK_GL_ADD_UNIFORM (1, CROSS_FADE_PROGRESS, u_progress) GSK_GL_ADD_UNIFORM (2, CROSS_FADE_SOURCE2, u_source2)) GSK_GL_DEFINE_PROGRAM (filled_border, - "/org/gtk/libgsk/gl/filled_border.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("filled_border.glsl")), GSK_GL_ADD_UNIFORM (1, FILLED_BORDER_WIDTHS, u_widths) GSK_GL_ADD_UNIFORM (2, FILLED_BORDER_OUTLINE_RECT, u_outline_rect)) GSK_GL_DEFINE_PROGRAM (inset_shadow, - "/org/gtk/libgsk/gl/inset_shadow.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("inset_shadow.glsl")), GSK_GL_ADD_UNIFORM (1, INSET_SHADOW_SPREAD, u_spread) GSK_GL_ADD_UNIFORM (2, INSET_SHADOW_OFFSET, u_offset) GSK_GL_ADD_UNIFORM (3, INSET_SHADOW_OUTLINE_RECT, u_outline_rect)) GSK_GL_DEFINE_PROGRAM (linear_gradient, - "/org/gtk/libgsk/gl/linear_gradient.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("linear_gradient.glsl")), GSK_GL_ADD_UNIFORM (1, LINEAR_GRADIENT_COLOR_STOPS, u_color_stops) GSK_GL_ADD_UNIFORM (2, LINEAR_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops) GSK_GL_ADD_UNIFORM (3, LINEAR_GRADIENT_POINTS, u_points) GSK_GL_ADD_UNIFORM (4, LINEAR_GRADIENT_REPEAT, u_repeat)) GSK_GL_DEFINE_PROGRAM (outset_shadow, - "/org/gtk/libgsk/gl/outset_shadow.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("outset_shadow.glsl")), GSK_GL_ADD_UNIFORM (1, OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect)) GSK_GL_DEFINE_PROGRAM (radial_gradient, - "/org/gtk/libgsk/gl/radial_gradient.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("radial_gradient.glsl")), GSK_GL_ADD_UNIFORM (1, RADIAL_GRADIENT_COLOR_STOPS, u_color_stops) GSK_GL_ADD_UNIFORM (2, RADIAL_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops) GSK_GL_ADD_UNIFORM (3, RADIAL_GRADIENT_REPEAT, u_repeat) @@ -73,12 +73,12 @@ GSK_GL_DEFINE_PROGRAM (radial_gradient, GSK_GL_ADD_UNIFORM (5, RADIAL_GRADIENT_GEOMETRY, u_geometry)) GSK_GL_DEFINE_PROGRAM (repeat, - "/org/gtk/libgsk/gl/repeat.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("repeat.glsl")), GSK_GL_ADD_UNIFORM (1, REPEAT_CHILD_BOUNDS, u_child_bounds) GSK_GL_ADD_UNIFORM (2, REPEAT_TEXTURE_RECT, u_texture_rect)) GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow, - "/org/gtk/libgsk/gl/unblurred_outset_shadow.glsl", + GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("unblurred_outset_shadow.glsl")), GSK_GL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread) GSK_GL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset) GSK_GL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))