diff --git a/clutter/clutter/clutter-blur-effect.c b/clutter/clutter/clutter-blur-effect.c index 99331dce2..92aeca697 100644 --- a/clutter/clutter/clutter-blur-effect.c +++ b/clutter/clutter/clutter-blur-effect.c @@ -126,6 +126,7 @@ clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect, static gboolean clutter_blur_effect_pre_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterEffectClass *parent_class; @@ -143,7 +144,7 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect, } parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class); - return parent_class->pre_paint (effect, paint_context); + return parent_class->pre_paint (effect, node, paint_context); } static gboolean diff --git a/clutter/clutter/clutter-brightness-contrast-effect.c b/clutter/clutter/clutter-brightness-contrast-effect.c index aa196fa20..4942b8772 100644 --- a/clutter/clutter/clutter-brightness-contrast-effect.c +++ b/clutter/clutter/clutter-brightness-contrast-effect.c @@ -140,6 +140,7 @@ clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effe static gboolean clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); @@ -164,7 +165,7 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect, parent_class = CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class); - return parent_class->pre_paint (effect, paint_context); + return parent_class->pre_paint (effect, node, paint_context); } static void diff --git a/clutter/clutter/clutter-colorize-effect.c b/clutter/clutter/clutter-colorize-effect.c index 8b8aba1d7..d73a0524f 100644 --- a/clutter/clutter/clutter-colorize-effect.c +++ b/clutter/clutter/clutter-colorize-effect.c @@ -114,6 +114,7 @@ clutter_colorize_effect_create_pipeline (ClutterOffscreenEffect *effect, static gboolean clutter_colorize_effect_pre_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterEffectClass *parent_class; @@ -131,7 +132,7 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect, } parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class); - return parent_class->pre_paint (effect, paint_context); + return parent_class->pre_paint (effect, node, paint_context); } static void diff --git a/clutter/clutter/clutter-desaturate-effect.c b/clutter/clutter/clutter-desaturate-effect.c index 4e4ea8213..d7035b679 100644 --- a/clutter/clutter/clutter-desaturate-effect.c +++ b/clutter/clutter/clutter-desaturate-effect.c @@ -125,6 +125,7 @@ clutter_desaturate_effect_create_pipeline (ClutterOffscreenEffect *effect, static gboolean clutter_desaturate_effect_pre_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterEffectClass *parent_class; @@ -142,7 +143,7 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect, } parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class); - return parent_class->pre_paint (effect, paint_context); + return parent_class->pre_paint (effect, node, paint_context); } static void diff --git a/clutter/clutter/clutter-effect.c b/clutter/clutter/clutter-effect.c index 1df651f20..4e33cca45 100644 --- a/clutter/clutter/clutter-effect.c +++ b/clutter/clutter/clutter-effect.c @@ -180,6 +180,7 @@ G_DEFINE_ABSTRACT_TYPE (ClutterEffect, static gboolean clutter_effect_real_pre_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { return TRUE; @@ -187,6 +188,7 @@ clutter_effect_real_pre_paint (ClutterEffect *effect, static void clutter_effect_real_post_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { } @@ -216,28 +218,23 @@ clutter_effect_real_paint_node (ClutterEffect *effect, static void clutter_effect_real_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context, ClutterEffectPaintFlags flags) { ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect); - ClutterPaintNode *node; gboolean pre_paint_succeeded; /* The default implementation provides a compatibility wrapper for effects that haven't migrated to use the 'paint' virtual yet. This just calls the old pre and post virtuals before chaining on */ - pre_paint_succeeded = effect_class->pre_paint (effect, paint_context); - - node = clutter_effect_node_new (effect); + pre_paint_succeeded = effect_class->pre_paint (effect, node,paint_context); effect_class->paint_node (effect, node, paint_context, flags); - clutter_paint_node_paint (node, paint_context); if (pre_paint_succeeded) - effect_class->post_paint (effect, paint_context); - - clutter_paint_node_unref (node); + effect_class->post_paint (effect, node, paint_context); } static void @@ -291,9 +288,19 @@ _clutter_effect_paint (ClutterEffect *effect, ClutterPaintContext *paint_context, ClutterEffectPaintFlags flags) { + ClutterPaintNode *node; + g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, paint_context, flags); + node = clutter_effect_node_new (effect); + + CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, + node, + paint_context, + flags); + + clutter_paint_node_paint (node, paint_context); + clutter_paint_node_unref (node); } void diff --git a/clutter/clutter/clutter-effect.h b/clutter/clutter/clutter-effect.h index d15015cf9..8969fcd78 100644 --- a/clutter/clutter/clutter-effect.h +++ b/clutter/clutter/clutter-effect.h @@ -77,14 +77,17 @@ struct _ClutterEffectClass /*< public >*/ gboolean (* pre_paint) (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context); void (* post_paint) (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context); gboolean (* modify_paint_volume) (ClutterEffect *effect, ClutterPaintVolume *volume); void (* paint) (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context, ClutterEffectPaintFlags flags); void (* paint_node) (ClutterEffect *effect, diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c index 4871562b7..598adb316 100644 --- a/clutter/clutter/clutter-offscreen-effect.c +++ b/clutter/clutter/clutter-offscreen-effect.c @@ -99,8 +99,6 @@ struct _ClutterOffscreenEffectPrivate int target_width; int target_height; - gint old_opacity_override; - gulong purge_handler_id; }; @@ -270,6 +268,7 @@ update_fbo (ClutterEffect *effect, static gboolean clutter_offscreen_effect_pre_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); @@ -279,7 +278,6 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect, ClutterActor *stage; graphene_matrix_t projection, modelview; const ClutterPaintVolume *volume; - CoglColor transparent; gfloat stage_width, stage_height; gfloat target_width = -1, target_height = -1; float resource_scale; @@ -336,7 +334,6 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect, goto disable_effect; offscreen = COGL_FRAMEBUFFER (priv->offscreen); - clutter_paint_context_push_framebuffer (paint_context, offscreen); /* We don't want the FBO contents to be transformed. That could waste memory * (e.g. during zoom), or result in something that's not rectangular (clipped @@ -363,22 +360,6 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect, cogl_framebuffer_set_projection_matrix (offscreen, &projection); - cogl_color_init_from_4ub (&transparent, 0, 0, 0, 0); - cogl_framebuffer_clear (offscreen, - COGL_BUFFER_BIT_COLOR | - COGL_BUFFER_BIT_DEPTH, - &transparent); - - cogl_framebuffer_push_matrix (offscreen); - - /* Override the actor's opacity to fully opaque - we paint the offscreen - * texture with the actor's paint opacity, so we need to do this to avoid - * multiplying the opacity twice. - */ - priv->old_opacity_override = - clutter_actor_get_opacity_override (priv->actor); - clutter_actor_set_opacity_override (priv->actor, 0xff); - return TRUE; disable_effect: @@ -425,63 +406,57 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect, static void clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterOffscreenEffectPrivate *priv = effect->priv; - CoglFramebuffer *framebuffer = - clutter_paint_context_get_framebuffer (paint_context); + graphene_matrix_t transform; float resource_scale; - cogl_framebuffer_push_matrix (framebuffer); + graphene_matrix_init_translate (&transform, + &GRAPHENE_POINT3D_INIT (priv->fbo_offset_x, + priv->fbo_offset_y, + 0.0f)); - /* The current modelview matrix is *almost* perfect already. It's only - * missing a correction for the expanded FBO and offset rendering within... - */ resource_scale = clutter_actor_get_resource_scale (priv->actor); - if (resource_scale != 1.0f) { float paint_scale = 1.0f / resource_scale; - cogl_framebuffer_scale (framebuffer, paint_scale, paint_scale, 1.f); + graphene_matrix_scale (&transform, paint_scale, paint_scale, 1.f); } - cogl_framebuffer_translate (framebuffer, - priv->fbo_offset_x, - priv->fbo_offset_y, - 0.0f); + if (!graphene_matrix_is_identity (&transform)) + { + ClutterPaintNode *transform_node; + + transform_node = clutter_transform_node_new (&transform); + clutter_paint_node_set_static_name (transform_node, + "ClutterOffscreenEffect (transform)"); + clutter_paint_node_add_child (node, transform_node); + clutter_paint_node_unref (transform_node); + + node = transform_node; + } /* paint the target material; this is virtualized for * sub-classes that require special hand-holding */ - clutter_offscreen_effect_paint_target (effect, paint_context); - - cogl_framebuffer_pop_matrix (framebuffer); + clutter_offscreen_effect_paint_target (effect, node, paint_context); } static void clutter_offscreen_effect_post_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffectPrivate *priv = self->priv; - CoglFramebuffer *framebuffer; g_warn_if_fail (priv->offscreen); g_warn_if_fail (priv->pipeline); g_warn_if_fail (priv->actor); - /* Restore the previous opacity override */ - if (priv->actor) - { - clutter_actor_set_opacity_override (priv->actor, - priv->old_opacity_override); - } - - framebuffer = clutter_paint_context_get_framebuffer (paint_context); - cogl_framebuffer_pop_matrix (framebuffer); - clutter_paint_context_pop_framebuffer (paint_context); - - clutter_offscreen_effect_paint_texture (self, paint_context); + clutter_offscreen_effect_paint_texture (self, node, paint_context); } static void @@ -520,15 +495,18 @@ clutter_offscreen_effect_paint_node (ClutterEffect *effect, static void clutter_offscreen_effect_paint (ClutterEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context, ClutterEffectPaintFlags flags) { ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffectPrivate *priv = self->priv; + ClutterEffectClass *parent_class = + CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class); if (flags & CLUTTER_EFFECT_PAINT_BYPASS_EFFECT) { - clutter_actor_continue_paint (priv->actor, paint_context); + add_actor_node (self, node, -1); g_clear_object (&priv->offscreen); return; } @@ -537,14 +515,9 @@ clutter_offscreen_effect_paint (ClutterEffect *effect, * then we can just use the cached image in the FBO. */ if (priv->offscreen == NULL || (flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY)) - { - ClutterEffectClass *parent_class = - CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class); - - parent_class->paint (effect, paint_context, flags); - } + parent_class->paint (effect, node, paint_context, flags); else - clutter_offscreen_effect_paint_texture (self, paint_context); + clutter_offscreen_effect_paint_texture (self, node, paint_context); } static void @@ -659,6 +632,7 @@ clutter_offscreen_effect_get_pipeline (ClutterOffscreenEffect *effect) /** * clutter_offscreen_effect_paint_target: * @effect: a #ClutterOffscreenEffect + * @node: a #ClutterPaintNode * @paint_context: a #ClutterPaintContext * * Calls the paint_target() virtual function of the @effect @@ -667,19 +641,14 @@ clutter_offscreen_effect_get_pipeline (ClutterOffscreenEffect *effect) */ void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context) { - ClutterPaintNode *node; - g_return_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect)); - node = clutter_effect_node_new (CLUTTER_EFFECT (effect)); - CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect, node, paint_context); - clutter_paint_node_paint (node, paint_context); - clutter_paint_node_unref (node); } /** diff --git a/clutter/clutter/clutter-offscreen-effect.h b/clutter/clutter/clutter-offscreen-effect.h index a53c269ff..b06bc34ed 100644 --- a/clutter/clutter/clutter-offscreen-effect.h +++ b/clutter/clutter/clutter-offscreen-effect.h @@ -106,6 +106,7 @@ CoglHandle clutter_offscreen_effect_get_texture (ClutterOffscree CLUTTER_EXPORT void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintNode *node, ClutterPaintContext *paint_context); CLUTTER_EXPORT CoglHandle clutter_offscreen_effect_create_texture (ClutterOffscreenEffect *effect,