[gtk+/wip/otte/shader: 127/127] gsk: Add GskSlEnvironment
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 127/127] gsk: Add GskSlEnvironment
- Date: Fri, 13 Oct 2017 00:07:07 +0000 (UTC)
commit 6811f83b2caac1cc4dc54dd73835eccda6e72e1a
Author: Benjamin Otte <otte redhat com>
Date: Fri Oct 13 00:48:46 2017 +0200
gsk: Add GskSlEnvironment
This is the object that is meant to hold information about different GL
versions and take care of intializing native functions and variables at
the start of parsing.
gsk/gskslcompiler.c | 2 +-
gsk/gskslcompiler.h | 3 +-
gsk/gskslenvironment.c | 98 ++++++++++++++++++++++++++++++++++++++
gsk/gskslenvironmentprivate.h | 41 ++++++++++++++++
gsk/gskslnativefunction.c | 47 +++++++++++++++---
gsk/gskslnativefunctionprivate.h | 3 +-
gsk/gskslpreprocessor.c | 43 +++++++++++++++--
gsk/gskslpreprocessorprivate.h | 2 +
gsk/gskslprogram.c | 7 ++-
gsk/gskslscope.c | 17 -------
gsk/gsksltypesprivate.h | 1 +
gsk/meson.build | 1 +
12 files changed, 231 insertions(+), 34 deletions(-)
---
diff --git a/gsk/gskslcompiler.c b/gsk/gskslcompiler.c
index a789ba1..8af9579 100644
--- a/gsk/gskslcompiler.c
+++ b/gsk/gskslcompiler.c
@@ -239,7 +239,7 @@ gsk_sl_compiler_compile (GskSlCompiler *compiler,
program = g_object_new (GSK_TYPE_SL_PROGRAM, NULL);
- preproc = gsk_sl_preprocessor_new (compiler, source);
+ preproc = gsk_sl_preprocessor_new (compiler, NULL, source);
gsk_sl_program_parse (program, preproc);
diff --git a/gsk/gskslcompiler.h b/gsk/gskslcompiler.h
index 16c2f2e..6746e56 100644
--- a/gsk/gskslcompiler.h
+++ b/gsk/gskslcompiler.h
@@ -44,7 +44,8 @@ typedef enum {
GSK_SL_COMPILER_WARNING_CONSTANT,
GSK_SL_COMPILER_WARNING_DEAD_CODE,
GSK_SL_COMPILER_WARNING_SHADOW,
- GSK_SL_COMPILER_WARNING_UNIMPLEMENTED
+ GSK_SL_COMPILER_WARNING_UNIMPLEMENTED,
+ GSK_SL_COMPILER_WARNING_VERSION
} GskSlCompilerWarning;
#define GSK_SL_COMPILER_ERROR (gsk_sl_compiler_error_quark ())
diff --git a/gsk/gskslenvironment.c b/gsk/gskslenvironment.c
new file mode 100644
index 0000000..f9c5ef2
--- /dev/null
+++ b/gsk/gskslenvironment.c
@@ -0,0 +1,98 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright © 2017 Benjamin Otte <otte gnome org>
+ *
+ * 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 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/>.
+ */
+
+#include "config.h"
+
+#include "gskslenvironmentprivate.h"
+
+#include "gskslnativefunctionprivate.h"
+#include "gskslscopeprivate.h"
+
+#include <string.h>
+
+struct _GskSlEnvironment
+{
+ int ref_count;
+
+ GskSlProfile profile;
+ guint version;
+};
+
+GskSlEnvironment *
+gsk_sl_environment_new (GskSlProfile profile,
+ guint version)
+{
+ GskSlEnvironment *environment;
+
+ environment = g_slice_new0 (GskSlEnvironment);
+ environment->ref_count = 1;
+
+ environment->profile = profile;
+ environment->version = version;
+
+ return environment;
+}
+
+GskSlEnvironment *
+gsk_sl_environment_ref (GskSlEnvironment *environment)
+{
+ g_return_val_if_fail (environment != NULL, NULL);
+
+ environment->ref_count += 1;
+
+ return environment;
+}
+
+void
+gsk_sl_environment_unref (GskSlEnvironment *environment)
+{
+ if (environment == NULL)
+ return;
+
+ environment->ref_count -= 1;
+ if (environment->ref_count > 0)
+ return;
+
+ g_slice_free (GskSlEnvironment, environment);
+}
+
+
+GskSlProfile
+gsk_sl_environment_get_profile (GskSlEnvironment *environment)
+{
+ return environment->profile;
+}
+
+guint
+gsk_sl_environment_get_version (GskSlEnvironment *environment)
+{
+ return environment->version;
+}
+
+GskSlScope *
+gsk_sl_environment_create_scope (GskSlEnvironment *environment)
+{
+ GskSlScope *scope;
+
+ scope = gsk_sl_scope_new (NULL, NULL);
+
+ gsk_sl_native_functions_add (scope, environment);
+
+ return scope;
+}
+
diff --git a/gsk/gskslenvironmentprivate.h b/gsk/gskslenvironmentprivate.h
new file mode 100644
index 0000000..5e73f1c
--- /dev/null
+++ b/gsk/gskslenvironmentprivate.h
@@ -0,0 +1,41 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright © 2017 Benjamin Otte <otte gnome org>
+ *
+ * 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 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/>.
+ */
+
+#ifndef __GSK_SL_ENVIRONMENT_PRIVATE_H__
+#define __GSK_SL_ENVIRONMENT_PRIVATE_H__
+
+#include <glib.h>
+
+#include "gsksltypesprivate.h"
+
+G_BEGIN_DECLS
+
+GskSlEnvironment * gsk_sl_environment_new (GskSlProfile profile,
+ guint version);
+
+GskSlEnvironment * gsk_sl_environment_ref (GskSlEnvironment *environment);
+void gsk_sl_environment_unref (GskSlEnvironment *environment);
+
+GskSlProfile gsk_sl_environment_get_profile (GskSlEnvironment *environment);
+guint gsk_sl_environment_get_version (GskSlEnvironment *environment);
+
+GskSlScope * gsk_sl_environment_create_scope (GskSlEnvironment *environment);
+
+G_END_DECLS
+
+#endif /* __GSK_SL_ENVIRONMENT_PRIVATE_H__ */
diff --git a/gsk/gskslnativefunction.c b/gsk/gskslnativefunction.c
index ca91ddb..3283a3e 100644
--- a/gsk/gskslnativefunction.c
+++ b/gsk/gskslnativefunction.c
@@ -20,13 +20,17 @@
#include "gskslnativefunctionprivate.h"
+#include "gskslenvironmentprivate.h"
+#include "gskslfunctionprivate.h"
+#include "gskslscopeprivate.h"
+
#define NATIVE1(type, name, arg1) \
{ name, GSK_SL_BUILTIN_ ## type, 1, (GskSlBuiltinType[1]) { GSK_SL_BUILTIN_ ## arg1 } }
#define NATIVE2(type, name, arg1, arg2) \
{ name, GSK_SL_BUILTIN_ ## type, 2, (GskSlBuiltinType[2]) { GSK_SL_BUILTIN_ ## arg1, GSK_SL_BUILTIN_ ##
arg2 } }
#define NATIVE3(type, name, arg1, arg2, arg3) \
{ name, GSK_SL_BUILTIN_ ## type, 3, (GskSlBuiltinType[3]) { GSK_SL_BUILTIN_ ## arg1, GSK_SL_BUILTIN_ ##
arg2, GSK_SL_BUILTIN_ ## arg3, } }
-const GskSlNativeFunction gsk_glsl_functions[] = {
+static const GskSlNativeFunction gsk_glsl_functions[] = {
NATIVE1 (FLOAT, "radians", FLOAT),
NATIVE1 (VEC2, "radians", VEC2),
NATIVE1 (VEC3, "radians", VEC3),
@@ -248,12 +252,10 @@ const GskSlNativeFunction gsk_glsl_functions[] = {
NATIVE1 (BVEC2, "not", BVEC2),
NATIVE1 (BVEC3, "not", BVEC3),
NATIVE1 (BVEC4, "not", BVEC4),
-#if 0
{ NULL }
};
static const GskSlNativeFunction gsk_glsl_functions_120[] = {
-#endif
NATIVE2 (MAT2, "outerProduct", VEC2, VEC2),
NATIVE2 (MAT3, "outerProduct", VEC3, VEC3),
NATIVE2 (MAT4, "outerProduct", VEC4, VEC4),
@@ -278,12 +280,10 @@ static const GskSlNativeFunction gsk_glsl_functions_120[] = {
NATIVE2 (MAT3X4, "matrixCompMult", MAT3X4, MAT3X4),
NATIVE2 (MAT4X2, "matrixCompMult", MAT4X2, MAT4X2),
NATIVE2 (MAT4X3, "matrixCompMult", MAT4X3, MAT4X3),
-#if 0
{ NULL }
};
static const GskSlNativeFunction gsk_glsl_functions_130[] = {
-#endif
NATIVE1 (FLOAT, "sinh", FLOAT),
NATIVE1 (VEC2, "sinh", VEC2),
NATIVE1 (VEC3, "sinh", VEC3),
@@ -406,12 +406,10 @@ static const GskSlNativeFunction gsk_glsl_functions_130[] = {
NATIVE2 (BVEC2, "notEqual", UVEC2, UVEC2),
NATIVE2 (BVEC3, "notEqual", UVEC3, UVEC3),
NATIVE2 (BVEC4, "notEqual", UVEC4, UVEC4),
-#if 0
{ NULL }
};
static const GskSlNativeFunction gsk_glsl_functions_150[] = {
-#endif
NATIVE1 (FLOAT, "determinant", MAT2),
NATIVE1 (FLOAT, "determinant", MAT3),
NATIVE1 (FLOAT, "determinant", MAT4),
@@ -421,3 +419,38 @@ static const GskSlNativeFunction gsk_glsl_functions_150[] = {
{ NULL }
};
+static void
+gsk_sl_native_functions_add_list (GskSlScope *scope,
+ const GskSlNativeFunction *functions)
+{
+ guint i;
+
+ for (i = 0; functions[i].name; i++)
+ {
+ GskSlFunction *function = gsk_sl_function_new_native (&functions[i]);
+ gsk_sl_scope_add_function (scope, function);
+ gsk_sl_function_unref (function);
+ }
+}
+
+void
+gsk_sl_native_functions_add (GskSlScope *scope,
+ GskSlEnvironment *environment)
+{
+ guint version = gsk_sl_environment_get_version (environment);
+
+ gsk_sl_native_functions_add_list (scope, gsk_glsl_functions);
+
+ if (version < 120)
+ return;
+ gsk_sl_native_functions_add_list (scope, gsk_glsl_functions_120);
+
+ if (version < 130)
+ return;
+ gsk_sl_native_functions_add_list (scope, gsk_glsl_functions_130);
+
+ if (version < 150)
+ return;
+ gsk_sl_native_functions_add_list (scope, gsk_glsl_functions_150);
+}
+
diff --git a/gsk/gskslnativefunctionprivate.h b/gsk/gskslnativefunctionprivate.h
index 5d787f0..02a3ae3 100644
--- a/gsk/gskslnativefunctionprivate.h
+++ b/gsk/gskslnativefunctionprivate.h
@@ -33,7 +33,8 @@ struct _GskSlNativeFunction
const GskSlBuiltinType *argument_types;
};
-extern const GskSlNativeFunction gsk_glsl_functions[];
+void gsk_sl_native_functions_add (GskSlScope *scope,
+ GskSlEnvironment *environment);
G_END_DECLS
diff --git a/gsk/gskslpreprocessor.c b/gsk/gskslpreprocessor.c
index bf22097..e7e3de2 100644
--- a/gsk/gskslpreprocessor.c
+++ b/gsk/gskslpreprocessor.c
@@ -23,6 +23,7 @@
#include "gskcodesource.h"
#include "gskslcompilerprivate.h"
#include "gsksldefineprivate.h"
+#include "gskslenvironmentprivate.h"
#include "gsksltokenizerprivate.h"
typedef struct _GskSlPpToken GskSlPpToken;
@@ -37,6 +38,7 @@ struct _GskSlPreprocessor
int ref_count;
GskSlCompiler *compiler;
+ GskSlEnvironment *environment;
GskSlTokenizer *tokenizer;
GSList *pending_tokenizers;
GArray *tokens;
@@ -99,6 +101,7 @@ gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc)
g_hash_table_destroy (preproc->defines);
g_slist_free_full (preproc->pending_tokenizers, (GDestroyNotify) gsk_sl_tokenizer_unref);
gsk_sl_tokenizer_unref (preproc->tokenizer);
+ gsk_sl_environment_unref (preproc->environment);
g_object_unref (preproc->compiler);
g_array_free (preproc->tokens, TRUE);
@@ -111,6 +114,12 @@ gsk_sl_preprocessor_has_fatal_error (GskSlPreprocessor *preproc)
return preproc->fatal_error;
}
+GskSlEnvironment *
+gsk_sl_preprocessor_get_environment (GskSlPreprocessor *preproc)
+{
+ return preproc->environment;
+}
+
static void
gsk_sl_preprocessor_push_conditional (GskSlPreprocessor *preproc,
GskConditional cond)
@@ -180,8 +189,29 @@ gsk_sl_preprocessor_handle_version (GskSlPreprocessor *preproc,
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, location, "#version directive must be first in
compilation.");
return;
}
-
- gsk_sl_preprocessor_warn_full (preproc, UNIMPLEMENTED, location, "#version directive not supported.");
+ if (preproc->environment)
+ {
+ if (gsk_sl_environment_get_profile (preproc->environment) == profile &&
+ gsk_sl_environment_get_version (preproc->environment) == version)
+ {
+ gsk_sl_preprocessor_warn_full (preproc, VERSION, location,
+ "#version directive should not be used, but it matches predefined
version.");
+ return;
+ }
+ else
+ {
+ GskSlProfile env_profile = gsk_sl_environment_get_profile (preproc->environment);
+ gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, location,
+ "#version directive not allowed. This compilation uses %u %s.",
+ gsk_sl_environment_get_version (preproc->environment),
+ env_profile == GSK_SL_PROFILE_ES ? "es" :
+ env_profile == GSK_SL_PROFILE_COMPATIBILITY ? "compatibility" :
+ "core");
+ return;
+ }
+ }
+
+ preproc->environment = gsk_sl_environment_new (profile, version);
}
static gboolean
@@ -675,8 +705,9 @@ gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
}
GskSlPreprocessor *
-gsk_sl_preprocessor_new (GskSlCompiler *compiler,
- GskCodeSource *source)
+gsk_sl_preprocessor_new (GskSlCompiler *compiler,
+ GskSlEnvironment *environment,
+ GskCodeSource *source)
{
GskSlPreprocessor *preproc;
GskSlPpToken pp;
@@ -685,6 +716,8 @@ gsk_sl_preprocessor_new (GskSlCompiler *compiler,
preproc->ref_count = 1;
preproc->compiler = g_object_ref (compiler);
+ if (environment)
+ preproc->environment = gsk_sl_environment_ref (environment);
preproc->tokenizer = gsk_sl_tokenizer_new (source,
gsk_sl_preprocessor_error_func,
preproc,
@@ -704,6 +737,8 @@ gsk_sl_preprocessor_new (GskSlCompiler *compiler,
gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline);
gsk_sl_preprocessor_handle_token (preproc, &pp, TRUE, FALSE);
}
+ if (preproc->environment == NULL)
+ preproc->environment = gsk_sl_environment_new (GSK_SL_PROFILE_CORE, 150);
return preproc;
}
diff --git a/gsk/gskslpreprocessorprivate.h b/gsk/gskslpreprocessorprivate.h
index 3ea5939..29def72 100644
--- a/gsk/gskslpreprocessorprivate.h
+++ b/gsk/gskslpreprocessorprivate.h
@@ -26,12 +26,14 @@
G_BEGIN_DECLS
GskSlPreprocessor * gsk_sl_preprocessor_new (GskSlCompiler *compiler,
+ GskSlEnvironment *environment,
GskCodeSource *source);
GskSlPreprocessor * gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc);
void gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc);
gboolean gsk_sl_preprocessor_has_fatal_error (GskSlPreprocessor *preproc);
+GskSlEnvironment * gsk_sl_preprocessor_get_environment (GskSlPreprocessor *preproc);
const GskSlToken * gsk_sl_preprocessor_get (GskSlPreprocessor *preproc);
const GskCodeLocation * gsk_sl_preprocessor_get_location (GskSlPreprocessor *preproc);
void gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc,
diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c
index bbea1ca..e5a1066 100644
--- a/gsk/gskslprogram.c
+++ b/gsk/gskslprogram.c
@@ -21,7 +21,7 @@
#include "gskslprogramprivate.h"
#include "gsksldeclarationprivate.h"
-#include "gskslexpressionprivate.h"
+#include "gskslenvironmentprivate.h"
#include "gskslfunctionprivate.h"
#include "gskslpreprocessorprivate.h"
#include "gskslprinterprivate.h"
@@ -45,7 +45,7 @@ gsk_sl_program_dispose (GObject *object)
GskSlProgram *program = GSK_SL_PROGRAM (object);
g_slist_free_full (program->declarations, (GDestroyNotify) gsk_sl_declaration_unref);
- gsk_sl_scope_unref (program->scope);
+ g_clear_pointer (&program->scope, gsk_sl_scope_unref);
G_OBJECT_CLASS (gsk_sl_program_parent_class)->dispose (object);
}
@@ -61,7 +61,6 @@ gsk_sl_program_class_init (GskSlProgramClass *klass)
static void
gsk_sl_program_init (GskSlProgram *program)
{
- program->scope = gsk_sl_scope_new (NULL, NULL);
}
void
@@ -71,6 +70,8 @@ gsk_sl_program_parse (GskSlProgram *program,
GskSlDeclaration *declaration;
const GskSlToken *token;
+ program->scope = gsk_sl_environment_create_scope (gsk_sl_preprocessor_get_environment (preproc));
+
for (token = gsk_sl_preprocessor_get (preproc);
!gsk_sl_token_is (token, GSK_SL_TOKEN_EOF);
token = gsk_sl_preprocessor_get (preproc))
diff --git a/gsk/gskslscope.c b/gsk/gskslscope.c
index 97ff233..1d06b01 100644
--- a/gsk/gskslscope.c
+++ b/gsk/gskslscope.c
@@ -21,7 +21,6 @@
#include "gskslscopeprivate.h"
#include "gskslfunctionprivate.h"
-#include "gskslnativefunctionprivate.h"
#include "gsksltypeprivate.h"
#include "gskslvariableprivate.h"
@@ -45,19 +44,6 @@ free_function_list (gpointer data)
g_list_free_full (data, (GDestroyNotify) gsk_sl_function_unref);
}
-static void
-gsk_sl_scope_add_native_functions (GskSlScope *scope)
-{
- guint i;
-
- for (i = 0; gsk_glsl_functions[i].name; i++)
- {
- GskSlFunction *function = gsk_sl_function_new_native (&gsk_glsl_functions[i]);
- gsk_sl_scope_add_function (scope, function);
- gsk_sl_function_unref (function);
- }
-}
-
GskSlScope *
gsk_sl_scope_new (GskSlScope *parent,
GskSlType *return_type)
@@ -75,9 +61,6 @@ gsk_sl_scope_new (GskSlScope *parent,
scope->functions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)
free_function_list);
scope->types = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) gsk_sl_type_unref);
- if (!parent)
- gsk_sl_scope_add_native_functions (scope);
-
return scope;
}
diff --git a/gsk/gsksltypesprivate.h b/gsk/gsksltypesprivate.h
index dc11f8d..baadc3b 100644
--- a/gsk/gsksltypesprivate.h
+++ b/gsk/gsksltypesprivate.h
@@ -22,6 +22,7 @@
#include <gsk/gsktypes.h>
typedef struct _GskSlDeclaration GskSlDeclaration;
+typedef struct _GskSlEnvironment GskSlEnvironment;
typedef struct _GskSlExpression GskSlExpression;
typedef struct _GskSlFunction GskSlFunction;
typedef struct _GskSlFunctionMatcher GskSlFunctionMatcher;
diff --git a/gsk/meson.build b/gsk/meson.build
index 7f279d1..5935a35 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -38,6 +38,7 @@ gsk_private_sources = files([
'gskslbinary.c',
'gsksldeclaration.c',
'gsksldefine.c',
+ 'gskslenvironment.c',
'gskslexpression.c',
'gskslfunction.c',
'gskslfunctiontype.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]