diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index 46a1a8c87..be0254c6a 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -104,6 +104,7 @@ cogl_experimental_h = \
$(srcdir)/cogl-pipeline.h \
$(srcdir)/cogl-pipeline-state.h \
$(srcdir)/cogl-pipeline-layer-state.h \
+ $(srcdir)/cogl-snippet.h \
$(srcdir)/cogl2-path.h \
$(srcdir)/cogl2-clip-state.h \
$(srcdir)/cogl2-experimental.h \
@@ -329,6 +330,8 @@ cogl_sources_c = \
$(srcdir)/cogl-config.c \
$(srcdir)/cogl-boxed-value.h \
$(srcdir)/cogl-boxed-value.c \
+ $(srcdir)/cogl-snippet-private.h \
+ $(srcdir)/cogl-snippet.c \
$(NULL)
if SUPPORT_XLIB
diff --git a/cogl/cogl-snippet-private.h b/cogl/cogl-snippet-private.h
new file mode 100644
index 000000000..b7ee4a838
--- /dev/null
+++ b/cogl/cogl-snippet-private.h
@@ -0,0 +1,54 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * 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
+ * .
+ *
+ *
+ *
+ * Authors:
+ * Neil Roberts
+ */
+
+#ifndef __COGL_SNIPPET_PRIVATE_H
+#define __COGL_SNIPPET_PRIVATE_H
+
+#include
+
+#include "cogl-snippet.h"
+#include "cogl-object-private.h"
+
+struct _CoglSnippet
+{
+ CoglObject _parent;
+
+ /* This is set to TRUE the first time the snippet is attached to the
+ pipeline. After that any attempts to modify the snippet will be
+ ignored. */
+ gboolean immutable;
+
+ char *declarations;
+ char *pre;
+ char *post;
+};
+
+void
+_cogl_snippet_make_immutable (CoglSnippet *snippet);
+
+#endif /* __COGL_SNIPPET_PRIVATE_H */
+
diff --git a/cogl/cogl-snippet.c b/cogl/cogl-snippet.c
new file mode 100644
index 000000000..08b19a88d
--- /dev/null
+++ b/cogl/cogl-snippet.c
@@ -0,0 +1,145 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * 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
+ * .
+ *
+ *
+ *
+ * Authors:
+ * Neil Roberts
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cogl-snippet-private.h"
+#include "cogl-util.h"
+
+static void
+_cogl_snippet_free (CoglSnippet *snippet);
+
+COGL_OBJECT_DEFINE (Snippet, snippet);
+
+CoglSnippet *
+cogl_snippet_new (const char *declarations,
+ const char *post)
+{
+ CoglSnippet *snippet = g_slice_new0 (CoglSnippet);
+
+ _cogl_snippet_object_new (snippet);
+
+ cogl_snippet_set_declarations (snippet, declarations);
+ cogl_snippet_set_post (snippet, post);
+
+ return snippet;
+}
+
+static gboolean
+_cogl_snippet_modify (CoglSnippet *snippet)
+{
+ if (snippet->immutable)
+ {
+ g_warning ("A CoglSnippet should not be modified once it has been "
+ "attached to a pipeline. Any modifications after that point "
+ "will be ignored.");
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+cogl_snippet_set_declarations (CoglSnippet *snippet,
+ const char *declarations)
+{
+ _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet));
+
+ if (!_cogl_snippet_modify (snippet))
+ return;
+
+ g_free (snippet->declarations);
+ snippet->declarations = declarations ? g_strdup (declarations) : NULL;
+}
+
+const char *
+cogl_snippet_get_declarations (CoglSnippet *snippet)
+{
+ _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), NULL);
+
+ return snippet->declarations;
+}
+
+void
+cogl_snippet_set_pre (CoglSnippet *snippet,
+ const char *pre)
+{
+ _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet));
+
+ if (!_cogl_snippet_modify (snippet))
+ return;
+
+ g_free (snippet->pre);
+ snippet->pre = pre ? g_strdup (pre) : NULL;
+}
+
+const char *
+cogl_snippet_get_pre (CoglSnippet *snippet)
+{
+ _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), NULL);
+
+ return snippet->pre;
+}
+
+void
+cogl_snippet_set_post (CoglSnippet *snippet,
+ const char *post)
+{
+ _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet));
+
+ if (!_cogl_snippet_modify (snippet))
+ return;
+
+ g_free (snippet->post);
+ snippet->post = post ? g_strdup (post) : NULL;
+}
+
+const char *
+cogl_snippet_get_post (CoglSnippet *snippet)
+{
+ _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), NULL);
+
+ return snippet->post;
+}
+
+void
+_cogl_snippet_make_immutable (CoglSnippet *snippet)
+{
+ snippet->immutable = TRUE;
+}
+
+static void
+_cogl_snippet_free (CoglSnippet *snippet)
+{
+ g_free (snippet->declarations);
+ g_free (snippet->pre);
+ g_free (snippet->post);
+ g_slice_free (CoglSnippet, snippet);
+}
diff --git a/cogl/cogl-snippet.h b/cogl/cogl-snippet.h
new file mode 100644
index 000000000..7afa18a20
--- /dev/null
+++ b/cogl/cogl-snippet.h
@@ -0,0 +1,195 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * 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
+ * .
+ *
+ *
+ *
+ * Authors:
+ * Neil Roberts
+ */
+
+#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __COGL_SNIPPET_H__
+#define __COGL_SNIPPET_H__
+
+#include
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION:cogl-snippet
+ * @short_description: Functions for creating and manipulating shader snippets
+ *
+ * ...
+ */
+typedef struct _CoglSnippet CoglSnippet;
+
+#define COGL_SNIPPET(OBJECT) ((CoglSnippet *)OBJECT)
+
+#define cogl_snippet_new cogl_snippet_new_EXP
+/**
+ * cogl_snippet_new:
+ * @declarations: The source code for the declarations for this
+ * snippet or %NULL. See cogl_snippet_set_declarations().
+ * @post: The source code to run after the hook point where this
+ * shader snippet is attached or %NULL. See cogl_snippet_set_post().
+ *
+ * Allocates and initializes a new snippet with the given source strings.
+ *
+ * Return value: a pointer to a new #CoglSnippet
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+CoglSnippet *
+cogl_snippet_new (const char *declarations,
+ const char *post);
+
+#define cogl_is_snippet cogl_is_snippet_EXP
+/**
+ * cogl_is_snippet:
+ * @handle: A CoglHandle
+ *
+ * Gets whether the given handle references an existing snippet object.
+ *
+ * Return value: %TRUE if the handle references a #CoglSnippet,
+ * %FALSE otherwise
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+gboolean
+cogl_is_snippet (void *object);
+
+#define cogl_snippet_set_declarations cogl_snippet_set_declarations_EXP
+/**
+ * cogl_snippet_set_declarations:
+ * @snippet: A #CoglSnippet
+ * @declarations: The new source string for the declarations section
+ * of this snippet.
+ *
+ * Sets a source string that will be inserted in the global scope of
+ * the generated shader when this snippet is used on a pipeline. This
+ * string is typically used to declare uniforms, attributes or
+ * functions that will be used by the other parts of the snippets.
+ *
+ * This function should only be called before the snippet is attached
+ * to its first pipeline. After that the snippet should be considered
+ * immutable.
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+void
+cogl_snippet_set_declarations (CoglSnippet *snippet,
+ const char *declarations);
+
+#define cogl_snippet_get_declarations cogl_snippet_get_declarations_EXP
+/**
+ * cogl_snippet_get_declarations:
+ * @snippet: A #CoglSnippet
+ *
+ * Return value: the source string that was set with
+ * cogl_snippet_set_declarations() or %NULL if none was set.
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+const char *
+cogl_snippet_get_declarations (CoglSnippet *snippet);
+
+#define cogl_snippet_set_pre cogl_snippet_set_pre_EXP
+/**
+ * cogl_snippet_set_pre:
+ * @snippet: A #CoglSnippet
+ * @pre: The new source string for the pre section of this snippet.
+ *
+ * Sets a source string that will be inserted before the hook point in
+ * the generated shader for the pipeline that this snippet is attached
+ * to. Please see the documentation of each hook point in
+ * #CoglPipeline for a description of how this string should be used.
+ *
+ * This function should only be called before the snippet is attached
+ * to its first pipeline. After that the snippet should be considered
+ * immutable.
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+void
+cogl_snippet_set_pre (CoglSnippet *snippet,
+ const char *pre);
+
+#define cogl_snippet_get_pre cogl_snippet_get_pre_EXP
+/**
+ * cogl_snippet_get_pre:
+ * @snippet: A #CoglSnippet
+ *
+ * Return value: the source string that was set with
+ * cogl_snippet_set_pre() or %NULL if none was set.
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+const char *
+cogl_snippet_get_pre (CoglSnippet *snippet);
+
+#define cogl_snippet_set_post cogl_snippet_set_post_EXP
+/**
+ * cogl_snippet_set_post:
+ * @snippet: A #CoglSnippet
+ * @post: The new source string for the post section of this snippet.
+ *
+ * Sets a source string that will be inserted after the hook point in
+ * the generated shader for the pipeline that this snippet is attached
+ * to. Please see the documentation of each hook point in
+ * #CoglPipeline for a description of how this string should be used.
+ *
+ * This function should only be called before the snippet is attached
+ * to its first pipeline. After that the snippet should be considered
+ * immutable.
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+void
+cogl_snippet_set_post (CoglSnippet *snippet,
+ const char *post);
+
+#define cogl_snippet_get_post cogl_snippet_get_post_EXP
+/**
+ * cogl_snippet_get_post:
+ * @snippet: A #CoglSnippet
+ *
+ * Return value: the source string that was set with
+ * cogl_snippet_set_post() or %NULL if none was set.
+ *
+ * Since: 1.10
+ * Stability: Unstable
+ */
+const char *
+cogl_snippet_get_post (CoglSnippet *snippet);
+
+G_END_DECLS
+
+#endif /* __COGL_SNIPPET_H__ */
diff --git a/cogl/cogl.h b/cogl/cogl.h
index 772886b88..ec2ccc785 100644
--- a/cogl/cogl.h
+++ b/cogl/cogl.h
@@ -94,6 +94,7 @@ typedef struct _CoglFramebuffer CoglFramebuffer;
#include
#include
#include
+#include
#include
#include
#if defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)