summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2012-08-30 01:45:17 +0200
committerGiovanni Campagna <gcampagna@src.gnome.org>2012-11-05 19:12:37 +0100
commit859ea1457d77582ab6c0d0776e2b3402856f3e72 (patch)
treeeabcc0b62bc079ebebfe65144ac9d4ed5e69ce46
parent188d53243844afeeebc33dc9a68425ee1af9f576 (diff)
downloadmutter-859ea1457d77582ab6c0d0776e2b3402856f3e72.tar.gz
Add the ability to add shader hooks to MetaBackgroundActor
Using ClutterEffect is not pratical on MetaBackgroundActor, as the FBO redirection has a noticeable performance impact. Instead, allow adding GLSL code directly to the pipeline used to draw the background texture. At the same time, port MetaBackgroundActor to modern Cogl API. https://bugzilla.gnome.org/show_bug.cgi?id=669798
-rw-r--r--src/Makefile.am2
-rw-r--r--src/compositor/meta-background-actor.c69
-rw-r--r--src/meta/meta-background-actor.h28
3 files changed, 85 insertions, 14 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d5b398c08..e9038a616 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -221,7 +221,7 @@ typelib_DATA = Meta-$(api_version).typelib
INTROSPECTION_GIRS = Meta-$(api_version).gir
Meta-$(api_version).gir: libmutter.la
-@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0
+@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0
@META_GIR@_EXPORT_PACKAGES = libmutter
@META_GIR@_CFLAGS = $(INCLUDES)
@META_GIR@_LIBS = libmutter.la
diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c
index d70ae1b6b..ea2bf388b 100644
--- a/src/compositor/meta-background-actor.c
+++ b/src/compositor/meta-background-actor.c
@@ -55,7 +55,7 @@ struct _MetaScreenBackground
float texture_width;
float texture_height;
- CoglHandle texture;
+ CoglTexture *texture;
CoglMaterialWrapMode wrap_mode;
guint have_pixmap : 1;
};
@@ -63,7 +63,8 @@ struct _MetaScreenBackground
struct _MetaBackgroundActorPrivate
{
MetaScreenBackground *background;
- CoglHandle material;
+ CoglPipeline *pipeline;
+
cairo_region_t *visible_region;
float dim_factor;
};
@@ -140,7 +141,7 @@ update_wrap_mode_of_actor (MetaBackgroundActor *self)
{
MetaBackgroundActorPrivate *priv = self->priv;
- cogl_material_set_layer_wrap_mode (priv->material, 0, priv->background->wrap_mode);
+ cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, priv->background->wrap_mode);
}
static void
@@ -174,7 +175,7 @@ set_texture_on_actor (MetaBackgroundActor *self)
* the underlying X pixmap is already gone has the tendency to trigger
* X errors inside DRI. For safety, trap errors */
meta_error_trap_push (display);
- cogl_material_set_layer (priv->material, 0, priv->background->texture);
+ cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->background->texture);
meta_error_trap_pop (display);
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
@@ -210,7 +211,7 @@ set_texture (MetaScreenBackground *background,
update_wrap_mode (background);
}
-/* Sets our material to paint with a 1x1 texture of the stage's background
+/* Sets our pipeline to paint with a 1x1 texture of the stage's background
* color; doing this when we have no pixmap allows the application to turn
* off painting the stage. There might be a performance benefit to
* painting in this case with a solid color, but the normal solid color
@@ -250,11 +251,7 @@ meta_background_actor_dispose (GObject *object)
priv->background = NULL;
}
- if (priv->material != COGL_INVALID_HANDLE)
- {
- cogl_handle_unref (priv->material);
- priv->material = COGL_INVALID_HANDLE;
- }
+ g_clear_pointer(&priv->pipeline, cogl_object_unref);
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
}
@@ -309,13 +306,13 @@ meta_background_actor_paint (ClutterActor *actor)
color_component = (int)(0.5 + opacity * priv->dim_factor);
- cogl_material_set_color4ub (priv->material,
+ cogl_pipeline_set_color4ub (priv->pipeline,
color_component,
color_component,
color_component,
opacity);
- cogl_set_source (priv->material);
+ cogl_set_source (priv->pipeline);
if (priv->visible_region)
{
@@ -483,7 +480,8 @@ meta_background_actor_new_for_screen (MetaScreen *screen)
priv->background = meta_screen_background_get (screen);
priv->background->actors = g_slist_prepend (priv->background->actors, self);
- priv->material = meta_create_texture_material (NULL);
+ /* A CoglMaterial and a CoglPipeline are the same thing */
+ priv->pipeline = (CoglPipeline*) meta_create_texture_material (NULL);
set_texture_on_actor (self);
update_wrap_mode_of_actor (self);
@@ -625,3 +623,48 @@ meta_background_actor_screen_size_changed (MetaScreen *screen)
for (l = background->actors; l; l = l->next)
clutter_actor_queue_relayout (l->data);
}
+
+/**
+ * meta_background_actor_add_glsl_snippet:
+ * @actor: a #MetaBackgroundActor
+ * @hook: where to insert the code
+ * @declarations: GLSL declarations
+ * @code: GLSL code
+ * @is_replace: wheter Cogl code should be replaced by the custom shader
+ *
+ * Adds a GLSL snippet to the pipeline used for drawing the background.
+ * See #CoglSnippet for details.
+ */
+void
+meta_background_actor_add_glsl_snippet (MetaBackgroundActor *actor,
+ MetaSnippetHook hook,
+ const char *declarations,
+ const char *code,
+ gboolean is_replace)
+{
+ MetaBackgroundActorPrivate *priv;
+ CoglSnippet *snippet;
+
+ g_return_if_fail (META_IS_BACKGROUND_ACTOR (actor));
+
+ priv = actor->priv;
+
+ if (is_replace)
+ {
+ snippet = cogl_snippet_new (hook, declarations, NULL);
+ cogl_snippet_set_replace (snippet, code);
+ }
+ else
+ {
+ snippet = cogl_snippet_new (hook, declarations, code);
+ }
+
+ if (hook == COGL_SNIPPET_HOOK_VERTEX ||
+ hook == COGL_SNIPPET_HOOK_FRAGMENT)
+ cogl_pipeline_add_snippet (priv->pipeline, snippet);
+ else
+ cogl_pipeline_add_layer_snippet (priv->pipeline, 0, snippet);
+
+ cogl_object_unref (snippet);
+}
+
diff --git a/src/meta/meta-background-actor.h b/src/meta/meta-background-actor.h
index 74f83db23..6efcc2529 100644
--- a/src/meta/meta-background-actor.h
+++ b/src/meta/meta-background-actor.h
@@ -62,4 +62,32 @@ GType meta_background_actor_get_type (void);
ClutterActor *meta_background_actor_new_for_screen (MetaScreen *screen);
+/**
+ * MetaSnippetHook:
+ * Temporary hack to work around Cogl not exporting CoglSnippetHook in
+ * the 1.0 API. Don't use.
+ */
+typedef enum {
+ /* Per pipeline vertex hooks */
+ META_SNIPPET_HOOK_VERTEX = 0,
+ META_SNIPPET_HOOK_VERTEX_TRANSFORM,
+
+ /* Per pipeline fragment hooks */
+ META_SNIPPET_HOOK_FRAGMENT = 2048,
+
+ /* Per layer vertex hooks */
+ META_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM = 4096,
+
+ /* Per layer fragment hooks */
+ META_SNIPPET_HOOK_LAYER_FRAGMENT = 6144,
+ META_SNIPPET_HOOK_TEXTURE_LOOKUP
+} MetaSnippetHook;
+
+
+void meta_background_actor_add_glsl_snippet (MetaBackgroundActor *actor,
+ MetaSnippetHook hook,
+ const char *declarations,
+ const char *code,
+ gboolean is_replace);
+
#endif /* META_BACKGROUND_ACTOR_H */