gl renderer: Rewrite shader builder

Use a unified approach to write both vertex and fragment shader in the
same file.
This commit is contained in:
Timm Bäder 2019-12-14 22:06:12 +01:00
parent d12dde07c3
commit cc909b160f
29 changed files with 478 additions and 761 deletions

View File

@ -10,7 +10,7 @@
#include "gskrendererprivate.h"
#include "gskrendernodeprivate.h"
#include "gsktransformprivate.h"
#include "gskshaderbuilderprivate.h"
#include "gskglshaderbuilderprivate.h"
#include "gskglglyphcacheprivate.h"
#include "gskgliconcacheprivate.h"
#include "gskglrenderopsprivate.h"
@ -411,19 +411,19 @@ struct _GskGLRenderer
union {
Program programs[GL_N_PROGRAMS];
struct {
Program blend_program;
Program blit_program;
Program blur_program;
Program border_program;
Program color_matrix_program;
Program color_program;
Program coloring_program;
Program color_matrix_program;
Program linear_gradient_program;
Program blur_program;
Program inset_shadow_program;
Program outset_shadow_program;
Program unblurred_outset_shadow_program;
Program border_program;
Program cross_fade_program;
Program blend_program;
Program inset_shadow_program;
Program linear_gradient_program;
Program outset_shadow_program;
Program repeat_program;
Program unblurred_outset_shadow_program;
};
};
@ -2677,92 +2677,76 @@ static gboolean
gsk_gl_renderer_create_programs (GskGLRenderer *self,
GError **error)
{
GskShaderBuilder *builder;
GError *shader_error = NULL;
GskGLShaderBuilder shader_builder;
int i;
static const struct {
const char *resource_path;
const char *name;
const char *fs;
const char *vs;
} program_definitions[] = {
{ "blit", "blit.fs.glsl" },
{ "color", "color.fs.glsl" },
{ "coloring", "coloring.fs.glsl" },
{ "color matrix", "color_matrix.fs.glsl" },
{ "linear gradient", "linear_gradient.fs.glsl" },
{ "blur", "blur.fs.glsl" },
{ "inset shadow", "inset_shadow.fs.glsl" },
{ "outset shadow", "outset_shadow.fs.glsl" },
{ "unblurred outset shadow", "unblurred_outset_shadow.fs.glsl" },
{ "border", "border.fs.glsl" },
{ "cross fade", "cross_fade.fs.glsl" },
{ "blend", "blend.fs.glsl" },
{ "repeat", "repeat.fs.glsl" },
{ "/org/gtk/libgsk/glsl/blend.glsl", "blend" },
{ "/org/gtk/libgsk/glsl/blit.glsl", "blit" },
{ "/org/gtk/libgsk/glsl/blur.glsl", "blur" },
{ "/org/gtk/libgsk/glsl/border.glsl", "border" },
{ "/org/gtk/libgsk/glsl/color_matrix.glsl", "color matrix" },
{ "/org/gtk/libgsk/glsl/color.glsl", "color" },
{ "/org/gtk/libgsk/glsl/coloring.glsl", "coloring" },
{ "/org/gtk/libgsk/glsl/cross_fade.glsl", "cross fade" },
{ "/org/gtk/libgsk/glsl/inset_shadow.glsl", "inset shadow" },
{ "/org/gtk/libgsk/glsl/linear_gradient.glsl", "linear gradient" },
{ "/org/gtk/libgsk/glsl/outset_shadow.glsl", "outset shadow" },
{ "/org/gtk/libgsk/glsl/repeat.glsl", "repeat" },
{ "/org/gtk/libgsk/glsl/unblurred_outset_shadow.glsl", "unblurred_outset shadow" },
};
gboolean success = TRUE;
builder = gsk_shader_builder_new ();
gsk_gl_shader_builder_init (&shader_builder,
"/org/gtk/libgsk/glsl/preamble.vs.glsl",
"/org/gtk/libgsk/glsl/preamble.fs.glsl");
gsk_shader_builder_set_resource_base_path (builder, "/org/gtk/libgsk/glsl");
g_assert (G_N_ELEMENTS (program_definitions) == GL_N_PROGRAMS);
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SHADERS))
shader_builder.debugging = TRUE;
#endif
if (gdk_gl_context_get_use_es (self->gl_context))
{
gsk_shader_builder_set_version (builder, SHADER_VERSION_GLES);
gsk_shader_builder_set_vertex_preamble (builder, "es2_common.vs.glsl");
gsk_shader_builder_set_fragment_preamble (builder, "es2_common.fs.glsl");
gsk_shader_builder_add_define (builder, "GSK_GLES", "1");
gsk_gl_shader_builder_set_glsl_version (&shader_builder, SHADER_VERSION_GLES);
shader_builder.gles = TRUE;
}
else if (gdk_gl_context_is_legacy (self->gl_context))
{
int maj, min;
gdk_gl_context_get_version (self->gl_context, &maj, &min);
if (maj == 3)
gsk_shader_builder_set_version (builder, SHADER_VERSION_GL3_LEGACY);
gsk_gl_shader_builder_set_glsl_version (&shader_builder, SHADER_VERSION_GL3_LEGACY);
else
gsk_shader_builder_set_version (builder, SHADER_VERSION_GL2_LEGACY);
gsk_gl_shader_builder_set_glsl_version (&shader_builder, SHADER_VERSION_GL2_LEGACY);
gsk_shader_builder_set_vertex_preamble (builder, "gl_common.vs.glsl");
gsk_shader_builder_set_fragment_preamble (builder, "gl_common.fs.glsl");
gsk_shader_builder_add_define (builder, "GSK_LEGACY", "1");
shader_builder.legacy = TRUE;
}
else
{
gsk_shader_builder_set_version (builder, SHADER_VERSION_GL3);
gsk_shader_builder_set_vertex_preamble (builder, "gl3_common.vs.glsl");
gsk_shader_builder_set_fragment_preamble (builder, "gl3_common.fs.glsl");
gsk_shader_builder_add_define (builder, "GSK_GL3", "1");
gsk_gl_shader_builder_set_glsl_version (&shader_builder, SHADER_VERSION_GL3);
shader_builder.gl3 = TRUE;
}
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SHADERS))
gsk_shader_builder_add_define (builder, "GSK_DEBUG", "1");
#endif
gsk_shader_builder_set_common_vertex_shader (builder, "blit.vs.glsl",
&shader_error);
g_assert_no_error (shader_error);
for (i = 0; i < GL_N_PROGRAMS; i ++)
{
Program *prog = &self->programs[i];
prog->index = i;
prog->id = gsk_shader_builder_create_program (builder,
program_definitions[i].fs,
program_definitions[i].vs,
&shader_error);
if (shader_error != NULL)
prog->id = gsk_gl_shader_builder_create_program (&shader_builder,
program_definitions[i].resource_path,
error);
if (prog->id < 0)
{
g_propagate_prefixed_error (error, shader_error,
"Unable to create '%s' program (from %s and %s):\n",
program_definitions[i].name,
program_definitions[i].fs,
program_definitions[i].vs);
g_object_unref (builder);
return FALSE;
success = FALSE;
goto out;
}
INIT_COMMON_UNIFORM_LOCATION (prog, alpha);
@ -2772,7 +2756,6 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_COMMON_UNIFORM_LOCATION (prog, projection);
INIT_COMMON_UNIFORM_LOCATION (prog, modelview);
}
/* color */
INIT_PROGRAM_UNIFORM_LOCATION (color, color);
@ -2827,8 +2810,10 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_PROGRAM_UNIFORM_LOCATION (repeat, child_bounds);
INIT_PROGRAM_UNIFORM_LOCATION (repeat, texture_rect);
g_object_unref (builder);
return TRUE;
out:
gsk_gl_shader_builder_finish (&shader_builder);
return success;
}
static GskGLTextureAtlases *

198
gsk/gl/gskglshaderbuilder.c Normal file
View File

@ -0,0 +1,198 @@
#include "config.h"
#include "gskglshaderbuilderprivate.h"
#include "gskdebugprivate.h"
#include <gdk/gdk.h>
#include <epoxy/gl.h>
void
gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
const char *vs_preamble_resource_path,
const char *fs_preamble_resource_path)
{
memset (self, 0, sizeof (*self));
self->vs_preamble = g_resources_lookup_data (vs_preamble_resource_path, 0, NULL);
self->fs_preamble = g_resources_lookup_data (fs_preamble_resource_path, 0, NULL);
g_assert (self->vs_preamble);
g_assert (self->fs_preamble);
}
void
gsk_gl_shader_builder_finish (GskGLShaderBuilder *self)
{
g_bytes_unref (self->vs_preamble);
g_bytes_unref (self->fs_preamble);
}
void
gsk_gl_shader_builder_set_glsl_version (GskGLShaderBuilder *self,
int version)
{
self->version = version;
}
static gboolean
check_shader_error (int shader_id,
GError **error)
{
int status;
int log_len;
char *buffer;
int code_len;
char *code;
glGetShaderiv (shader_id, GL_COMPILE_STATUS, &status);
if (G_LIKELY (status == GL_TRUE))
return TRUE;
glGetShaderiv (shader_id, GL_INFO_LOG_LENGTH, &log_len);
buffer = g_malloc0 (log_len + 1);
glGetShaderInfoLog (shader_id, log_len, NULL, buffer);
glGetShaderiv (shader_id, GL_SHADER_SOURCE_LENGTH, &code_len);
code = g_malloc0 (code_len + 1);
glGetShaderSource (shader_id, code_len, NULL, code);
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
"Compilation failure in shader.\nError message: %s\n\nSource code:\n%s\n\n",
buffer,
code);
g_free (buffer);
g_free (code);
return FALSE;
}
int
gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
const char *resource_path,
GError **error)
{
GBytes *source_bytes = g_resources_lookup_data (resource_path, 0, NULL);
char version_buffer[64];
const char *source;
const char *vertex_shader_start;
const char *fragment_shader_start;
int vertex_id;
int fragment_id;
int program_id = -1;
int status;
g_assert (source_bytes);
source = g_bytes_get_data (source_bytes, NULL);
vertex_shader_start = strstr (source, "VERTEX_SHADER");
fragment_shader_start = strstr (source, "FRAGMENT_SHADER");
g_assert (vertex_shader_start);
g_assert (fragment_shader_start);
/* They both start at the next newline */
vertex_shader_start = strstr (vertex_shader_start, "\n");
fragment_shader_start = strstr (fragment_shader_start, "\n");
g_snprintf (version_buffer, sizeof (version_buffer),
"#version %d\n", self->version);
vertex_id = glCreateShader (GL_VERTEX_SHADER);
glShaderSource (vertex_id, 7,
(const char *[]) {
version_buffer,
self->debugging ? "#define GSK_DEBUG 1\n" : "",
self->legacy ? "#define GSK_LEGACY 1\n" : "",
self->gl3 ? "#define GSK_GL3 1\n" : "",
self->gles ? "#define GSK_GLES 1\n" : "",
g_bytes_get_data (self->vs_preamble, NULL),
vertex_shader_start
},
(int[]) {
-1,
-1,
-1,
-1,
-1,
-1,
fragment_shader_start - vertex_shader_start
});
glCompileShader (vertex_id);
if (!check_shader_error (vertex_id, error))
{
glDeleteShader (vertex_id);
goto out;
}
fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource (fragment_id, 7,
(const char *[]) {
version_buffer,
self->debugging ? "#define GSK_DEBUG 1\n" : "",
self->legacy ? "#define GSK_LEGACY 1\n" : "",
self->gl3 ? "#define GSK_GL3 1\n" : "",
self->gles ? "#define GSK_GLES 1\n" : "",
g_bytes_get_data (self->fs_preamble, NULL),
fragment_shader_start
},
(int[]) {
-1,
-1,
-1,
-1,
-1,
-1,
-1,
});
glCompileShader (fragment_id);
if (!check_shader_error (fragment_id, error))
{
glDeleteShader (fragment_id);
goto out;
}
program_id = glCreateProgram ();
glAttachShader (program_id, vertex_id);
glAttachShader (program_id, fragment_id);
glLinkProgram (program_id);
glGetProgramiv (program_id, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
char *buffer = NULL;
int log_len = 0;
glGetProgramiv (program_id, GL_INFO_LOG_LENGTH, &log_len);
buffer = g_malloc0 (log_len + 1);
glGetProgramInfoLog (program_id, log_len, NULL, buffer);
g_warning ("Linking failure in shader:\n%s", buffer);
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED,
"Linking failure in shader: %s", buffer);
g_free (buffer);
glDeleteProgram (program_id);
goto out;
}
glDetachShader (program_id, vertex_id);
glDeleteShader (vertex_id);
glDetachShader (program_id, fragment_id);
glDeleteShader (fragment_id);
out:
g_bytes_unref (source_bytes);
return program_id;
}

View File

@ -0,0 +1,38 @@
#ifndef __GSK_SHADER_BUILDER_PRIVATE_H__
#define __GSK_SHADER_BUILDER_PRIVATE_H__
#include <gdk/gdk.h>
#include <graphene.h>
G_BEGIN_DECLS
typedef struct
{
GBytes *vs_preamble;
GBytes *fs_preamble;
int version;
guint debugging: 1;
guint gles: 1;
guint gl3: 1;
guint legacy: 1;
} GskGLShaderBuilder;
void gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
const char *vs_preamble_resource_path,
const char *fs_preamble_resource_path);
void gsk_gl_shader_builder_finish (GskGLShaderBuilder *self);
void gsk_gl_shader_builder_set_glsl_version (GskGLShaderBuilder *self,
int version);
int gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
const char *resource_path,
GError **error);
G_END_DECLS
#endif /* __GSK_SHADER_BUILDER_PRIVATE_H__ */

View File

@ -1,334 +0,0 @@
#include "config.h"
#include "gskshaderbuilderprivate.h"
#include "gskdebugprivate.h"
#include <gdk/gdk.h>
#include <epoxy/gl.h>
struct _GskShaderBuilder
{
GObject parent_instance;
char *resource_base_path;
char *vertex_preamble;
char *fragment_preamble;
int common_vertex_shader_id;
int version;
GPtrArray *defines;
/* We reuse this one for all the shaders */
GString *shader_code;
};
G_DEFINE_TYPE (GskShaderBuilder, gsk_shader_builder, G_TYPE_OBJECT)
static void
gsk_shader_builder_finalize (GObject *gobject)
{
GskShaderBuilder *self = GSK_SHADER_BUILDER (gobject);
g_free (self->resource_base_path);
g_free (self->vertex_preamble);
g_free (self->fragment_preamble);
g_string_free (self->shader_code, TRUE);
g_clear_pointer (&self->defines, g_ptr_array_unref);
if (self->common_vertex_shader_id > 0)
glDeleteShader (self->common_vertex_shader_id);
G_OBJECT_CLASS (gsk_shader_builder_parent_class)->finalize (gobject);
}
static void
gsk_shader_builder_class_init (GskShaderBuilderClass *klass)
{
G_OBJECT_CLASS (klass)->finalize = gsk_shader_builder_finalize;
}
static void
gsk_shader_builder_init (GskShaderBuilder *self)
{
self->defines = g_ptr_array_new_with_free_func (g_free);
self->shader_code = g_string_new (NULL);
}
GskShaderBuilder *
gsk_shader_builder_new (void)
{
return g_object_new (GSK_TYPE_SHADER_BUILDER, NULL);
}
void
gsk_shader_builder_set_resource_base_path (GskShaderBuilder *builder,
const char *base_path)
{
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
g_free (builder->resource_base_path);
builder->resource_base_path = g_strdup (base_path);
}
void
gsk_shader_builder_set_vertex_preamble (GskShaderBuilder *builder,
const char *vertex_preamble)
{
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
g_free (builder->vertex_preamble);
builder->vertex_preamble = g_strdup (vertex_preamble);
}
void
gsk_shader_builder_set_fragment_preamble (GskShaderBuilder *builder,
const char *fragment_preamble)
{
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
g_free (builder->fragment_preamble);
builder->fragment_preamble = g_strdup (fragment_preamble);
}
void
gsk_shader_builder_set_version (GskShaderBuilder *builder,
int version)
{
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
builder->version = version;
}
void
gsk_shader_builder_add_define (GskShaderBuilder *builder,
const char *define_name,
const char *define_value)
{
g_return_if_fail (GSK_IS_SHADER_BUILDER (builder));
g_return_if_fail (define_name != NULL && *define_name != '\0');
g_return_if_fail (define_value != NULL && *define_value != '\0');
g_ptr_array_add (builder->defines, g_strdup (define_name));
g_ptr_array_add (builder->defines, g_strdup (define_value));
}
static gboolean
lookup_shader_code (GString *code,
const char *base_path,
const char *shader_file,
GError **error)
{
GBytes *source;
char *path;
if (base_path != NULL)
path = g_build_filename (base_path, shader_file, NULL);
else
path = g_strdup (shader_file);
source = g_resources_lookup_data (path, 0, error);
g_free (path);
if (source == NULL)
return FALSE;
g_string_append (code, g_bytes_get_data (source, NULL));
g_bytes_unref (source);
return TRUE;
}
static int
gsk_shader_builder_compile_shader (GskShaderBuilder *builder,
int shader_type,
const char *shader_preamble,
const char *shader_source,
GError **error)
{
GString *code;
const char *source;
int shader_id;
int status;
int i;
/* Clear possibly previously set shader code */
g_string_erase (builder->shader_code, 0, -1);
code = builder->shader_code;
if (builder->version > 0)
{
g_string_append_printf (code, "#version %d\n", builder->version);
g_string_append_c (code, '\n');
}
for (i = 0; i < builder->defines->len; i += 2)
{
const char *name = g_ptr_array_index (builder->defines, i);
const char *value = g_ptr_array_index (builder->defines, i + 1);
g_string_append (code, "#define");
g_string_append_c (code, ' ');
g_string_append (code, name);
g_string_append_c (code, ' ');
g_string_append (code, value);
g_string_append_c (code, '\n');
}
g_string_append_c (code, '\n');
if (!lookup_shader_code (code, builder->resource_base_path, shader_preamble, error))
{
return -1;
}
g_string_append_c (code, '\n');
if (!lookup_shader_code (code, builder->resource_base_path, shader_source, error))
{
return -1;
}
source = code->str;
shader_id = glCreateShader (shader_type);
glShaderSource (shader_id, 1, (const GLchar **) &source, NULL);
glCompileShader (shader_id);
#ifdef G_ENABLE_DEBUG
if (GSK_DEBUG_CHECK (SHADERS))
{
g_print ("*** Compiling %s shader from '%s' + '%s' ***\n"
"%s\n",
shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
shader_preamble, shader_source,
source);
}
#endif
glGetShaderiv (shader_id, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
int log_len;
char *buffer;
glGetShaderiv (shader_id, GL_INFO_LOG_LENGTH, &log_len);
buffer = g_malloc0 (log_len + 1);
glGetShaderInfoLog (shader_id, log_len, NULL, buffer);
g_message ("\n%s\n", source);
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
"Compilation failure in %s shader:\n%s",
shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
buffer);
g_free (buffer);
glDeleteShader (shader_id);
return -1;
}
return shader_id;
}
void
gsk_shader_builder_set_common_vertex_shader (GskShaderBuilder *self,
const char *vertex_shader,
GError **error)
{
int shader_id;
shader_id = gsk_shader_builder_compile_shader (self,
GL_VERTEX_SHADER,
self->vertex_preamble,
vertex_shader,
error);
g_assert (shader_id > 0);
self->common_vertex_shader_id = shader_id;
}
int
gsk_shader_builder_create_program (GskShaderBuilder *builder,
const char *fragment_shader,
const char *vertex_shader,
GError **error)
{
int vertex_id;
int fragment_id;
int program_id;
int status;
g_return_val_if_fail (GSK_IS_SHADER_BUILDER (builder), -1);
g_return_val_if_fail (fragment_shader != NULL, -1);
g_return_val_if_fail (builder->common_vertex_shader_id != 0, -1);
if (vertex_shader == NULL)
vertex_id = builder->common_vertex_shader_id;
else
vertex_id = gsk_shader_builder_compile_shader (builder, GL_VERTEX_SHADER,
builder->vertex_preamble,
vertex_shader,
error);
if (vertex_id < 0)
return -1;
fragment_id = gsk_shader_builder_compile_shader (builder, GL_FRAGMENT_SHADER,
builder->fragment_preamble,
fragment_shader,
error);
if (fragment_id < 0)
{
glDeleteShader (vertex_id);
return -1;
}
program_id = glCreateProgram ();
glAttachShader (program_id, vertex_id);
glAttachShader (program_id, fragment_id);
glLinkProgram (program_id);
glGetProgramiv (program_id, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
char *buffer = NULL;
int log_len = 0;
glGetProgramiv (program_id, GL_INFO_LOG_LENGTH, &log_len);
buffer = g_malloc0 (log_len + 1);
glGetProgramInfoLog (program_id, log_len, NULL, buffer);
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED,
"Linking failure in shader:\n%s", buffer);
g_free (buffer);
glDeleteProgram (program_id);
program_id = -1;
goto out;
}
out:
if (vertex_id > 0)
{
/* We delete the common vertex shader when destroying the shader builder */
glDetachShader (program_id, vertex_id);
}
if (fragment_id > 0)
{
glDetachShader (program_id, fragment_id);
glDeleteShader (fragment_id);
}
return program_id;
}

View File

@ -1,39 +0,0 @@
#ifndef __GSK_SHADER_BUILDER_PRIVATE_H__
#define __GSK_SHADER_BUILDER_PRIVATE_H__
#include <gdk/gdk.h>
#include <graphene.h>
G_BEGIN_DECLS
#define GSK_TYPE_SHADER_BUILDER (gsk_shader_builder_get_type ())
G_DECLARE_FINAL_TYPE (GskShaderBuilder, gsk_shader_builder, GSK, SHADER_BUILDER, GObject)
GskShaderBuilder * gsk_shader_builder_new (void);
void gsk_shader_builder_set_version (GskShaderBuilder *builder,
int version);
void gsk_shader_builder_set_resource_base_path (GskShaderBuilder *builder,
const char *base_path);
void gsk_shader_builder_set_vertex_preamble (GskShaderBuilder *builder,
const char *shader_preamble);
void gsk_shader_builder_set_fragment_preamble (GskShaderBuilder *builder,
const char *shader_preamble);
void gsk_shader_builder_add_define (GskShaderBuilder *builder,
const char *define_name,
const char *define_value);
void gsk_shader_builder_set_common_vertex_shader (GskShaderBuilder *self,
const char *vertex_shader,
GError **error);
int gsk_shader_builder_create_program (GskShaderBuilder *builder,
const char *fragment_shader,
const char *vertex_shader,
GError **error);
G_END_DECLS
#endif /* __GSK_SHADER_BUILDER_PRIVATE_H__ */

View File

@ -1,24 +1,19 @@
gsk_private_gl_shaders = [
'resources/glsl/blit.fs.glsl',
'resources/glsl/blit.vs.glsl',
'resources/glsl/color.fs.glsl',
'resources/glsl/coloring.fs.glsl',
'resources/glsl/color_matrix.fs.glsl',
'resources/glsl/linear_gradient.fs.glsl',
'resources/glsl/blur.fs.glsl',
'resources/glsl/inset_shadow.fs.glsl',
'resources/glsl/outset_shadow.fs.glsl',
'resources/glsl/unblurred_outset_shadow.fs.glsl',
'resources/glsl/border.fs.glsl',
'resources/glsl/cross_fade.fs.glsl',
'resources/glsl/blend.fs.glsl',
'resources/glsl/repeat.fs.glsl',
'resources/glsl/es2_common.fs.glsl',
'resources/glsl/es2_common.vs.glsl',
'resources/glsl/gl3_common.fs.glsl',
'resources/glsl/gl3_common.vs.glsl',
'resources/glsl/gl_common.fs.glsl',
'resources/glsl/gl_common.vs.glsl',
'resources/glsl/preamble.fs.glsl',
'resources/glsl/preamble.vs.glsl',
'resources/glsl/border.glsl',
'resources/glsl/blit.glsl',
'resources/glsl/coloring.glsl',
'resources/glsl/color.glsl',
'resources/glsl/linear_gradient.glsl',
'resources/glsl/color_matrix.glsl',
'resources/glsl/blur.glsl',
'resources/glsl/inset_shadow.glsl',
'resources/glsl/outset_shadow.glsl',
'resources/glsl/unblurred_outset_shadow.glsl',
'resources/glsl/cross_fade.glsl',
'resources/glsl/blend.glsl',
'resources/glsl/repeat.glsl',
]
gsk_public_sources = files([
@ -38,7 +33,7 @@ gsk_private_sources = files([
'gskdebug.c',
'gskprivate.c',
'gskprofiler.c',
'gl/gskshaderbuilder.c',
'gl/gskglshaderbuilder.c',
'gl/gskglprofiler.c',
'gl/gskglglyphcache.c',
'gl/gskglimage.c',

View File

@ -1,3 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform int u_mode;
uniform sampler2D u_source2;
@ -264,73 +272,39 @@ void main() {
vec4 result;
if (u_mode == 0)
{
result = normal(top_color, bottom_color);
}
result = normal(top_color, bottom_color);
else if (u_mode == 1)
{
result = multiply(top_color, bottom_color);
}
result = multiply(top_color, bottom_color);
else if (u_mode == 2)
{
result = screen(top_color, bottom_color);
}
result = screen(top_color, bottom_color);
else if (u_mode == 3)
{
result = overlay(top_color, bottom_color);
}
result = overlay(top_color, bottom_color);
else if (u_mode == 4)
{
result = darken(top_color, bottom_color);
}
result = darken(top_color, bottom_color);
else if (u_mode == 5)
{
result = lighten(top_color, bottom_color);
}
result = lighten(top_color, bottom_color);
else if (u_mode == 6)
{
result = color_dodge(top_color, bottom_color);
}
result = color_dodge(top_color, bottom_color);
else if (u_mode == 7)
{
result = color_burn(top_color, bottom_color);
}
result = color_burn(top_color, bottom_color);
else if (u_mode == 8)
{
result = hard_light(top_color, bottom_color);
}
result = hard_light(top_color, bottom_color);
else if (u_mode == 9)
{
result = soft_light(top_color, bottom_color);
}
result = soft_light(top_color, bottom_color);
else if (u_mode == 10)
{
result = difference(top_color, bottom_color);
}
result = difference(top_color, bottom_color);
else if (u_mode == 11)
{
result = exclusion(top_color, bottom_color);
}
result = exclusion(top_color, bottom_color);
else if (u_mode == 12)
{
result = color(top_color, bottom_color);
}
result = color(top_color, bottom_color);
else if (u_mode == 13)
{
result = hue(top_color, bottom_color);
}
result = hue(top_color, bottom_color);
else if (u_mode == 14)
{
result = saturation(top_color, bottom_color);
}
result = saturation(top_color, bottom_color);
else if (u_mode == 15)
{
result = luminosity(top_color, bottom_color);
}
result = luminosity(top_color, bottom_color);
else
{
discard;
}
discard;
setOutputColor(result * u_alpha);
}

View File

@ -1,5 +0,0 @@
void main() {
vec4 diffuse = Texture(u_source, vUv);
setOutputColor(diffuse * u_alpha);
}

View File

@ -0,0 +1,13 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
void main() {
vec4 diffuse = Texture(u_source, vUv);
setOutputColor(diffuse * u_alpha);
}

View File

@ -1,5 +0,0 @@
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}

View File

@ -1,3 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform float u_blur_radius;
uniform vec2 u_blur_size;
uniform vec2 u_blur_dir;

View File

@ -1,3 +1,12 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform vec4 u_color;
uniform vec4 u_widths;
uniform RoundedRect u_outline_rect;

View File

@ -1,9 +0,0 @@
uniform vec4 u_color;
void main() {
vec4 color = u_color;
// Pre-multiply alpha
color.rgb *= color.a;
setOutputColor(color * u_alpha);
}

View File

@ -0,0 +1,18 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform vec4 u_color;
void main() {
vec4 color = u_color;
// Pre-multiply alpha
color.rgb *= color.a;
setOutputColor(color * u_alpha);
}

View File

@ -1,3 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform mat4 u_color_matrix;
uniform vec4 u_color_offset;

View File

@ -1,3 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform vec4 u_color;
void main() {

View File

@ -1,4 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform float u_progress;
uniform sampler2D u_source2;

View File

@ -1,103 +0,0 @@
precision mediump float;
uniform sampler2D u_source;
uniform mat4 u_projection;
uniform mat4 u_modelview;
uniform float u_alpha;
uniform vec4 u_viewport;
// In GtkSnapshot coordinates
uniform vec4 u_clip;
uniform vec4 u_clip_corner_widths;
uniform vec4 u_clip_corner_heights;
varying vec2 vUv;
struct RoundedRect
{
vec4 bounds;
vec4 corner_widths;
vec4 corner_heights;
};
float
ellipsis_dist (vec2 p, vec2 radius)
{
if (radius == vec2(0, 0))
return 0.0;
vec2 p0 = p / radius;
vec2 p1 = 2.0 * p0 / radius;
return (dot(p0, p0) - 1.0) / length (p1);
}
float
ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
{
float d = ellipsis_dist (point - center, radius);
return clamp (0.5 - d, 0.0, 1.0);
}
float
rounded_rect_coverage (RoundedRect r, vec2 p)
{
if (p.x < r.bounds.x || p.y < r.bounds.y ||
p.x >= r.bounds.z || p.y >= r.bounds.w)
return 0.0;
vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
float d_br = ellipsis_coverage(p, ref_br, rad_br);
float d_bl = ellipsis_coverage(p, ref_bl, rad_bl);
vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
p.x > ref_tr.x && p.y < ref_tr.y,
p.x > ref_br.x && p.y > ref_br.y,
p.x < ref_bl.x && p.y > ref_bl.y);
return 1.0 - dot(vec4(is_out), corner_coverages);
}
RoundedRect
rounded_rect_shrink (RoundedRect r, vec4 amount)
{
vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
vec4 new_widths = max (r.corner_widths - amount.wyyw, 0.0);
vec4 new_heights = max (r.corner_heights - amount.xxzz, 0.0);
return RoundedRect (new_bounds, new_widths, new_heights);
}
vec4 Texture(sampler2D sampler, vec2 texCoords) {
return texture2D(sampler, texCoords);
}
void setOutputColor(vec4 color) {
vec4 clipBounds = u_clip;
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
clipBounds.z = clipBounds.x + clipBounds.z;
clipBounds.w = clipBounds.y + clipBounds.w;
RoundedRect r = RoundedRect(clipBounds, u_clip_corner_widths, u_clip_corner_heights);
gl_FragColor = color * rounded_rect_coverage(r, f.xy);
/*gl_FragColor = color;*/
}

View File

@ -1,9 +0,0 @@
precision mediump float;
uniform mat4 u_projection;
uniform mat4 u_modelview;
attribute vec2 aPosition;
attribute vec2 aUv;
varying vec2 vUv;

View File

@ -1,7 +0,0 @@
uniform mat4 u_projection;
uniform mat4 u_modelview;
in vec2 aPosition;
in vec2 aUv;
out vec2 vUv;

View File

@ -1,100 +0,0 @@
uniform sampler2D u_source;
uniform mat4 u_projection;
uniform mat4 u_modelview;
uniform float u_alpha;
uniform vec4 u_viewport;
// In GtkSnapshot coordinates
uniform vec4 u_clip;
uniform vec4 u_clip_corner_widths;
uniform vec4 u_clip_corner_heights;
varying vec2 vUv;
struct RoundedRect
{
vec4 bounds;
vec4 corner_widths;
vec4 corner_heights;
};
float
ellipsis_dist (vec2 p, vec2 radius)
{
if (radius == vec2(0, 0))
return 0.0;
vec2 p0 = p / radius;
vec2 p1 = 2.0 * p0 / radius;
return (dot(p0, p0) - 1.0) / length (p1);
}
float
ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
{
float d = ellipsis_dist (point - center, radius);
return clamp (0.5 - d, 0.0, 1.0);
}
float
rounded_rect_coverage (RoundedRect r, vec2 p)
{
if (p.x < r.bounds.x || p.y < r.bounds.y ||
p.x >= r.bounds.z || p.y >= r.bounds.w)
return 0.0;
vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
float d_br = ellipsis_coverage(p, ref_br, rad_br);
float d_bl = ellipsis_coverage(p, ref_bl, rad_bl);
vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
p.x > ref_tr.x && p.y < ref_tr.y,
p.x > ref_br.x && p.y > ref_br.y,
p.x < ref_bl.x && p.y > ref_bl.y);
return 1.0 - dot(vec4(is_out), corner_coverages);
}
RoundedRect
rounded_rect_shrink (RoundedRect r, vec4 amount)
{
vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
vec4 new_widths = max (r.corner_widths - amount.wyyw, 0.0);
vec4 new_heights = max (r.corner_heights - amount.xxzz, 0.0);
return RoundedRect (new_bounds, new_widths, new_heights);
}
vec4 Texture(sampler2D sampler, vec2 texCoords) {
return texture2D(sampler, texCoords);
}
void setOutputColor(vec4 color) {
vec4 clipBounds = u_clip;
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
clipBounds.z = clipBounds.x + clipBounds.z;
clipBounds.w = clipBounds.y + clipBounds.w;
RoundedRect r = RoundedRect(clipBounds, u_clip_corner_widths, u_clip_corner_heights);
gl_FragColor = color * rounded_rect_coverage(r, f.xy);
}

View File

@ -1,7 +0,0 @@
uniform mat4 u_projection;
uniform mat4 u_modelview;
attribute vec2 aPosition;
attribute vec2 aUv;
varying vec2 vUv;

View File

@ -1,9 +1,16 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform float u_spread;
uniform vec4 u_color;
uniform vec2 u_offset;
uniform RoundedRect u_outline_rect;
void main() {
vec4 f = gl_FragCoord;

View File

@ -1,3 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform vec4 u_color_stops[8];
uniform float u_color_offsets[8];
uniform int u_num_color_stops;

View File

@ -1,3 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform RoundedRect u_outline_rect;
void main() {

View File

@ -1,8 +1,11 @@
#if GDK_GL3
precision highp float;
#endif
uniform sampler2D u_source;
uniform mat4 u_projection = mat4(1.0);
uniform mat4 u_modelview = mat4(1.0);
uniform mat4 u_projection;
uniform mat4 u_modelview;
uniform float u_alpha = 1.0;
uniform vec4 u_viewport;
@ -14,8 +17,15 @@ struct RoundedRect
uniform RoundedRect u_clip_rect;
#if GSK_GLES
varying vec2 vUv;
#elif GSK_LEGACY
varying vec2 vUv;
varying vec4 outputColor;
#else
in vec2 vUv;
out vec4 outputColor;
#endif
float
ellipsis_dist (vec2 p, vec2 radius)
@ -103,7 +113,11 @@ rounded_rect_shrink (RoundedRect r, vec4 amount)
}
vec4 Texture(sampler2D sampler, vec2 texCoords) {
#if GSK_GLES
return texture2D(sampler, texCoords);
#else
return texture(sampler, texCoords);
#endif
}
void setOutputColor(vec4 color) {
@ -112,6 +126,10 @@ void setOutputColor(vec4 color) {
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
#if GSK_GLES
gl_FragColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
#else
outputColor = color * rounded_rect_coverage(u_clip_rect, f.xy);
#endif
/*outputColor = color;*/
}

View File

@ -0,0 +1,17 @@
uniform mat4 u_projection;
uniform mat4 u_modelview;
#if GSK_GLES
attribute vec2 aPosition;
attribute vec2 aUv;
varying vec2 vUv;
#elif GSK_LEGACY
attribute vec2 aPosition;
attribute vec2 aUv;
varying vec2 vUv;
#else
in vec2 aPosition;
in vec2 aUv;
out vec2 vUv;
#endif

View File

@ -1,3 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform vec4 u_child_bounds;
uniform vec4 u_texture_rect;

View File

@ -1,3 +1,11 @@
// VERTEX_SHADER:
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
uniform float u_spread;
uniform vec4 u_color;
uniform vec2 u_offset;