forked from AuroraMiddleware/gtk
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:
parent
d12dde07c3
commit
cc909b160f
@ -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
198
gsk/gl/gskglshaderbuilder.c
Normal 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;
|
||||
}
|
||||
|
38
gsk/gl/gskglshaderbuilderprivate.h
Normal file
38
gsk/gl/gskglshaderbuilderprivate.h
Normal 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__ */
|
@ -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;
|
||||
}
|
@ -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__ */
|
@ -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',
|
||||
|
@ -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);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
void main() {
|
||||
vec4 diffuse = Texture(u_source, vUv);
|
||||
|
||||
setOutputColor(diffuse * u_alpha);
|
||||
}
|
13
gsk/resources/glsl/blit.glsl
Normal file
13
gsk/resources/glsl/blit.glsl
Normal 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);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
@ -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;
|
@ -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;
|
@ -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);
|
||||
}
|
18
gsk/resources/glsl/color.glsl
Normal file
18
gsk/resources/glsl/color.glsl
Normal 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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
@ -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;
|
||||
|
@ -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;*/
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
precision mediump float;
|
||||
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
|
||||
attribute vec2 aPosition;
|
||||
attribute vec2 aUv;
|
||||
|
||||
varying vec2 vUv;
|
@ -1,7 +0,0 @@
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
|
||||
in vec2 aPosition;
|
||||
in vec2 aUv;
|
||||
|
||||
out vec2 vUv;
|
@ -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);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_modelview;
|
||||
|
||||
attribute vec2 aPosition;
|
||||
attribute vec2 aUv;
|
||||
|
||||
varying vec2 vUv;
|
@ -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;
|
||||
|
@ -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;
|
@ -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() {
|
@ -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;*/
|
||||
}
|
17
gsk/resources/glsl/preamble.vs.glsl
Normal file
17
gsk/resources/glsl/preamble.vs.glsl
Normal 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
|
@ -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;
|
||||
|
@ -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;
|
Loading…
Reference in New Issue
Block a user