From 2593bbaadce7ff690f0d70deaee239d0a336c716 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 18 Feb 2011 15:44:17 +0000 Subject: [PATCH] Wrap shader stack into private functions The shader stack held by ClutterMainContext should only be accessed using functions, and not directly. Since it's a stack, we can use stack-like operations: push, pop and peek. --- clutter/clutter-actor.c | 28 ++++++++++++---------------- clutter/clutter-main.c | 29 +++++++++++++++++++++++++++++ clutter/clutter-private.h | 7 +++++-- clutter/clutter-texture.c | 19 +++++++++---------- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index e2974bff8..d2882acaf 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -9544,15 +9544,12 @@ clutter_actor_shader_pre_paint (ClutterActor *actor, { ShaderData *shader_data; ClutterShader *shader; - ClutterMainContext *context; shader_data = g_object_get_qdata (G_OBJECT (actor), quark_shader_data); if (shader_data == NULL) return; - context = _clutter_context_get_default (); shader = shader_data->shader; - if (shader != NULL) { clutter_shader_set_is_enabled (shader, TRUE); @@ -9560,7 +9557,7 @@ clutter_actor_shader_pre_paint (ClutterActor *actor, g_hash_table_foreach (shader_data->value_hash, set_each_param, shader); if (!repeat) - context->shaders = g_slist_prepend (context->shaders, actor); + _clutter_context_push_shader_stack (actor); } } @@ -9569,28 +9566,27 @@ clutter_actor_shader_post_paint (ClutterActor *actor) { ShaderData *shader_data; ClutterShader *shader; - ClutterMainContext *context; shader_data = g_object_get_qdata (G_OBJECT (actor), quark_shader_data); if (shader_data == NULL) return; - context = _clutter_context_get_default (); shader = shader_data->shader; - if (shader != NULL) { + ClutterActor *head; + clutter_shader_set_is_enabled (shader, FALSE); - context->shaders = g_slist_remove (context->shaders, actor); - if (context->shaders) - { - /* call pre-paint again, this time with the second argument being - * TRUE, indicating that we are reapplying the shader and thus - * should not be prepended to the stack - */ - clutter_actor_shader_pre_paint (context->shaders->data, TRUE); - } + /* remove the actor from the shaders stack; if there is another + * actor inside it, then call pre-paint again to set its shader + * but this time with the second argument being TRUE, indicating + * that we are re-applying an existing shader and thus should it + * not be prepended to the stack + */ + head = _clutter_context_pop_shader_stack (actor); + if (head != NULL) + clutter_actor_shader_pre_paint (head, TRUE); } } diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 4979834ea..58447d9f2 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -3276,3 +3276,32 @@ _clutter_context_get_pick_mode (void) return context->pick_mode; } + +void +_clutter_context_push_shader_stack (ClutterActor *actor) +{ + ClutterMainContext *context = _clutter_context_get_default (); + + context->shaders = g_slist_prepend (context->shaders, actor); +} + +ClutterActor * +_clutter_context_peek_shader_stack (void) +{ + ClutterMainContext *context = _clutter_context_get_default (); + + if (context->shaders != NULL) + return context->shaders->data; + + return NULL; +} + +ClutterActor * +_clutter_context_pop_shader_stack (ClutterActor *actor) +{ + ClutterMainContext *context = _clutter_context_get_default (); + + context->shaders = g_slist_remove (context->shaders, actor); + + return _clutter_context_peek_shader_stack (); +} diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 6450034a0..25d9d87a8 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -127,7 +127,7 @@ struct _ClutterMainContext ClutterActor *pointer_grab_actor; ClutterActor *keyboard_grab_actor; - /* stack of overridden shaders during paint */ + /* stack of actors with shaders during paint */ GSList *shaders; /* fb bit masks for col<->id mapping in picking */ @@ -170,12 +170,15 @@ typedef struct gboolean _clutter_threads_dispatch (gpointer data); void _clutter_threads_dispatch_free (gpointer data); -#define CLUTTER_CONTEXT() (_clutter_context_get_default ()) +#define CLUTTER_CONTEXT() (_clutter_context_get_default ()) ClutterMainContext * _clutter_context_get_default (void); gboolean _clutter_context_is_initialized (void); PangoContext * _clutter_context_create_pango_context (void); PangoContext * _clutter_context_get_pango_context (void); ClutterPickMode _clutter_context_get_pick_mode (void); +void _clutter_context_push_shader_stack (ClutterActor *actor); +ClutterActor * _clutter_context_pop_shader_stack (ClutterActor *actor); +ClutterActor * _clutter_context_peek_shader_stack (void); #define CLUTTER_PARAM_READABLE (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS) #define CLUTTER_PARAM_WRITABLE (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS) diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index 4e1058605..4080c438d 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -468,27 +468,26 @@ update_fbo (ClutterActor *self) { ClutterTexture *texture = CLUTTER_TEXTURE (self); ClutterTexturePrivate *priv = texture->priv; - ClutterMainContext *context; + ClutterActor *head; ClutterShader *shader = NULL; ClutterActor *stage = NULL; CoglMatrix projection; CoglColor transparent_col; - context = _clutter_context_get_default (); + head = _clutter_context_peek_shader_stack (); + if (head != NULL) + shader = clutter_actor_get_shader (head); - if (context->shaders) - shader = clutter_actor_get_shader (context->shaders->data); - - /* Temporarily turn off the shader on the top of the context's shader stack, - * to restore the GL pipeline to it's natural state. + /* Temporarily turn off the shader on the top of the context's + * shader stack, to restore the GL pipeline to it's natural state. */ - if (shader) + if (shader != NULL) clutter_shader_set_is_enabled (shader, FALSE); /* Redirect drawing to the fbo */ cogl_push_framebuffer (priv->fbo_handle); - if ((stage = clutter_actor_get_stage (self))) + if ((stage = clutter_actor_get_stage (self)) != NULL) { gfloat stage_width, stage_height; ClutterActor *source_parent; @@ -554,7 +553,7 @@ update_fbo (ClutterActor *self) cogl_pop_framebuffer (); /* If there is a shader on top of the shader stack, turn it back on. */ - if (shader) + if (shader != NULL) clutter_shader_set_is_enabled (shader, TRUE); }