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.
This commit is contained in:
Emmanuele Bassi 2011-02-18 15:44:17 +00:00
parent 28b0f8b938
commit 2593bbaadc
4 changed files with 55 additions and 28 deletions

View File

@ -9544,15 +9544,12 @@ clutter_actor_shader_pre_paint (ClutterActor *actor,
{ {
ShaderData *shader_data; ShaderData *shader_data;
ClutterShader *shader; ClutterShader *shader;
ClutterMainContext *context;
shader_data = g_object_get_qdata (G_OBJECT (actor), quark_shader_data); shader_data = g_object_get_qdata (G_OBJECT (actor), quark_shader_data);
if (shader_data == NULL) if (shader_data == NULL)
return; return;
context = _clutter_context_get_default ();
shader = shader_data->shader; shader = shader_data->shader;
if (shader != NULL) if (shader != NULL)
{ {
clutter_shader_set_is_enabled (shader, TRUE); 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); g_hash_table_foreach (shader_data->value_hash, set_each_param, shader);
if (!repeat) 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; ShaderData *shader_data;
ClutterShader *shader; ClutterShader *shader;
ClutterMainContext *context;
shader_data = g_object_get_qdata (G_OBJECT (actor), quark_shader_data); shader_data = g_object_get_qdata (G_OBJECT (actor), quark_shader_data);
if (shader_data == NULL) if (shader_data == NULL)
return; return;
context = _clutter_context_get_default ();
shader = shader_data->shader; shader = shader_data->shader;
if (shader != NULL) if (shader != NULL)
{ {
ClutterActor *head;
clutter_shader_set_is_enabled (shader, FALSE); clutter_shader_set_is_enabled (shader, FALSE);
context->shaders = g_slist_remove (context->shaders, actor); /* remove the actor from the shaders stack; if there is another
if (context->shaders) * actor inside it, then call pre-paint again to set its shader
{ * but this time with the second argument being TRUE, indicating
/* call pre-paint again, this time with the second argument being * that we are re-applying an existing shader and thus should it
* TRUE, indicating that we are reapplying the shader and thus * not be prepended to the stack
* should not be prepended to the stack
*/ */
clutter_actor_shader_pre_paint (context->shaders->data, TRUE); head = _clutter_context_pop_shader_stack (actor);
} if (head != NULL)
clutter_actor_shader_pre_paint (head, TRUE);
} }
} }

View File

@ -3276,3 +3276,32 @@ _clutter_context_get_pick_mode (void)
return context->pick_mode; 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 ();
}

View File

@ -127,7 +127,7 @@ struct _ClutterMainContext
ClutterActor *pointer_grab_actor; ClutterActor *pointer_grab_actor;
ClutterActor *keyboard_grab_actor; ClutterActor *keyboard_grab_actor;
/* stack of overridden shaders during paint */ /* stack of actors with shaders during paint */
GSList *shaders; GSList *shaders;
/* fb bit masks for col<->id mapping in picking */ /* fb bit masks for col<->id mapping in picking */
@ -176,6 +176,9 @@ gboolean _clutter_context_is_initialized (void);
PangoContext * _clutter_context_create_pango_context (void); PangoContext * _clutter_context_create_pango_context (void);
PangoContext * _clutter_context_get_pango_context (void); PangoContext * _clutter_context_get_pango_context (void);
ClutterPickMode _clutter_context_get_pick_mode (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_READABLE (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)
#define CLUTTER_PARAM_WRITABLE (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS) #define CLUTTER_PARAM_WRITABLE (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)

View File

@ -468,27 +468,26 @@ update_fbo (ClutterActor *self)
{ {
ClutterTexture *texture = CLUTTER_TEXTURE (self); ClutterTexture *texture = CLUTTER_TEXTURE (self);
ClutterTexturePrivate *priv = texture->priv; ClutterTexturePrivate *priv = texture->priv;
ClutterMainContext *context; ClutterActor *head;
ClutterShader *shader = NULL; ClutterShader *shader = NULL;
ClutterActor *stage = NULL; ClutterActor *stage = NULL;
CoglMatrix projection; CoglMatrix projection;
CoglColor transparent_col; 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) /* Temporarily turn off the shader on the top of the context's
shader = clutter_actor_get_shader (context->shaders->data); * 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); clutter_shader_set_is_enabled (shader, FALSE);
/* Redirect drawing to the fbo */ /* Redirect drawing to the fbo */
cogl_push_framebuffer (priv->fbo_handle); 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; gfloat stage_width, stage_height;
ClutterActor *source_parent; ClutterActor *source_parent;
@ -554,7 +553,7 @@ update_fbo (ClutterActor *self)
cogl_pop_framebuffer (); cogl_pop_framebuffer ();
/* If there is a shader on top of the shader stack, turn it back on. */ /* 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); clutter_shader_set_is_enabled (shader, TRUE);
} }