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;
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
/* 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
*/
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;
}
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 *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 */
@ -176,6 +176,9 @@ 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)

View File

@ -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);
}