clutter: Introduce paint contexts

When painting, actors rely on semi global state tracked by the state to
get various things needed for painting, such as the current draw
framebuffer. Having state hidden in such ways can be very deceiving as
it's hard to follow changes spread out, and adding more and more state
that should be tracked during a paint gets annoying as they will not
change in isolation but one by one in their own places. To do this
better, introduce a paint context that is passed along in paint calls
that contains the necessary state needed during painting.

The paint context implements a framebuffer stack just as Cogl works,
which is currently needed for offscreen rendering used by clutter.

The same context is passed around for paint nodes, contents and effects
as well.

In this commit, the context is only introduced, but not used. It aims to
replace the Cogl framebuffer stack, and will allow actors to know what
view it is currently painted on.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/935
This commit is contained in:
Jonas Ådahl 2019-11-13 22:21:58 +01:00 committed by Georges Basile Stavracas Neto
parent 5c986060f0
commit 49c8d42317
69 changed files with 563 additions and 175 deletions

View File

@ -3760,7 +3760,8 @@ add_or_remove_flatten_effect (ClutterActor *self)
} }
static void static void
clutter_actor_real_paint (ClutterActor *actor) clutter_actor_real_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
ClutterActorPrivate *priv = actor->priv; ClutterActorPrivate *priv = actor->priv;
ClutterActor *iter; ClutterActor *iter;
@ -3777,13 +3778,14 @@ clutter_actor_real_paint (ClutterActor *actor)
iter->priv->allocation.x2 - iter->priv->allocation.x1, iter->priv->allocation.x2 - iter->priv->allocation.x1,
iter->priv->allocation.y2 - iter->priv->allocation.y1); iter->priv->allocation.y2 - iter->priv->allocation.y1);
clutter_actor_paint (iter); clutter_actor_paint (iter, paint_context);
} }
} }
static gboolean static gboolean
clutter_actor_paint_node (ClutterActor *actor, clutter_actor_paint_node (ClutterActor *actor,
ClutterPaintNode *root) ClutterPaintNode *root,
ClutterPaintContext *paint_context)
{ {
ClutterActorPrivate *priv = actor->priv; ClutterActorPrivate *priv = actor->priv;
ClutterActorBox box; ClutterActorBox box;
@ -3847,7 +3849,7 @@ clutter_actor_paint_node (ClutterActor *actor,
} }
if (priv->content != NULL) if (priv->content != NULL)
_clutter_content_paint_content (priv->content, actor, root); _clutter_content_paint_content (priv->content, actor, root, paint_context);
if (CLUTTER_ACTOR_GET_CLASS (actor)->paint_node != NULL) if (CLUTTER_ACTOR_GET_CLASS (actor)->paint_node != NULL)
CLUTTER_ACTOR_GET_CLASS (actor)->paint_node (actor, root); CLUTTER_ACTOR_GET_CLASS (actor)->paint_node (actor, root);
@ -3863,7 +3865,7 @@ clutter_actor_paint_node (ClutterActor *actor,
} }
#endif /* CLUTTER_ENABLE_DEBUG */ #endif /* CLUTTER_ENABLE_DEBUG */
clutter_paint_node_paint (root); clutter_paint_node_paint (root, paint_context);
return TRUE; return TRUE;
} }
@ -3887,7 +3889,8 @@ clutter_actor_paint_node (ClutterActor *actor,
* unless it is performing a pick paint. * unless it is performing a pick paint.
*/ */
void void
clutter_actor_paint (ClutterActor *self) clutter_actor_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
g_autoptr (ClutterPaintNode) actor_node = NULL; g_autoptr (ClutterPaintNode) actor_node = NULL;
g_autoptr (ClutterPaintNode) root_node = NULL; g_autoptr (ClutterPaintNode) root_node = NULL;
@ -4069,7 +4072,7 @@ clutter_actor_paint (ClutterActor *self)
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES)) if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES))
_clutter_actor_draw_paint_volume (self, actor_node); _clutter_actor_draw_paint_volume (self, actor_node);
clutter_paint_node_paint (root_node); clutter_paint_node_paint (root_node, paint_context);
/* If we make it here then the actor has run through a complete /* If we make it here then the actor has run through a complete
paint run including all the effects so it's no longer dirty */ paint run including all the effects so it's no longer dirty */
@ -4089,7 +4092,8 @@ clutter_actor_paint (ClutterActor *self)
* Since: 1.8 * Since: 1.8
*/ */
void void
clutter_actor_continue_paint (ClutterActor *self) clutter_actor_continue_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
ClutterActorPrivate *priv; ClutterActorPrivate *priv;
@ -4122,15 +4126,15 @@ clutter_actor_continue_paint (ClutterActor *self)
/* XXX - for 1.12, we use the return value of paint_node() to /* XXX - for 1.12, we use the return value of paint_node() to
* decide whether we should emit the ::paint signal. * decide whether we should emit the ::paint signal.
*/ */
clutter_actor_paint_node (self, dummy); clutter_actor_paint_node (self, dummy, paint_context);
clutter_paint_node_unref (dummy); clutter_paint_node_unref (dummy);
/* XXX:2.0 - Call the paint() virtual directly */ /* XXX:2.0 - Call the paint() virtual directly */
if (g_signal_has_handler_pending (self, actor_signals[PAINT], if (g_signal_has_handler_pending (self, actor_signals[PAINT],
0, TRUE)) 0, TRUE))
g_signal_emit (self, actor_signals[PAINT], 0); g_signal_emit (self, actor_signals[PAINT], 0, paint_context);
else else
CLUTTER_ACTOR_GET_CLASS (self)->paint (self); CLUTTER_ACTOR_GET_CLASS (self)->paint (self, paint_context);
} }
else else
{ {
@ -4157,7 +4161,7 @@ clutter_actor_continue_paint (ClutterActor *self)
run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY; run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY;
} }
_clutter_effect_paint (priv->current_effect, run_flags); _clutter_effect_paint (priv->current_effect, paint_context, run_flags);
priv->current_effect = old_current_effect; priv->current_effect = old_current_effect;
} }
@ -8534,6 +8538,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
/** /**
* ClutterActor::paint: * ClutterActor::paint:
* @actor: the #ClutterActor that received the signal * @actor: the #ClutterActor that received the signal
* @paint_context: a #ClutterPaintContext
* *
* The ::paint signal is emitted each time an actor is being painted. * The ::paint signal is emitted each time an actor is being painted.
* *
@ -8561,7 +8566,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
G_SIGNAL_DEPRECATED, G_SIGNAL_DEPRECATED,
G_STRUCT_OFFSET (ClutterActorClass, paint), G_STRUCT_OFFSET (ClutterActorClass, paint),
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 0); G_TYPE_NONE, 1,
CLUTTER_TYPE_PAINT_CONTEXT);
/** /**
* ClutterActor::realize: * ClutterActor::realize:
* @actor: the #ClutterActor that received the signal * @actor: the #ClutterActor that received the signal

View File

@ -39,6 +39,7 @@
#include <clutter/clutter-types.h> #include <clutter/clutter-types.h>
#include <clutter/clutter-event.h> #include <clutter/clutter-event.h>
#include <clutter/clutter-paint-context.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -228,7 +229,8 @@ struct _ClutterActorClass
void (* unrealize) (ClutterActor *self); void (* unrealize) (ClutterActor *self);
void (* map) (ClutterActor *self); void (* map) (ClutterActor *self);
void (* unmap) (ClutterActor *self); void (* unmap) (ClutterActor *self);
void (* paint) (ClutterActor *self); void (* paint) (ClutterActor *self,
ClutterPaintContext *paint_context);
void (* parent_set) (ClutterActor *actor, void (* parent_set) (ClutterActor *actor,
ClutterActor *old_parent); ClutterActor *old_parent);
@ -349,9 +351,11 @@ void clutter_actor_map
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_unmap (ClutterActor *self); void clutter_actor_unmap (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_paint (ClutterActor *self); void clutter_actor_paint (ClutterActor *self,
ClutterPaintContext *paint_context);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_continue_paint (ClutterActor *self); void clutter_actor_continue_paint (ClutterActor *self,
ClutterPaintContext *paint_context);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_pick (ClutterActor *actor); void clutter_actor_pick (ClutterActor *actor);
CLUTTER_EXPORT CLUTTER_EXPORT

View File

@ -90,6 +90,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free)

View File

@ -99,7 +99,8 @@ G_DEFINE_TYPE (ClutterBlurEffect,
CLUTTER_TYPE_OFFSCREEN_EFFECT); CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean static gboolean
clutter_blur_effect_pre_paint (ClutterEffect *effect) clutter_blur_effect_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect); ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
ClutterEffectClass *parent_class; ClutterEffectClass *parent_class;
@ -124,7 +125,7 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect)
} }
parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class); parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class);
if (parent_class->pre_paint (effect)) if (parent_class->pre_paint (effect, paint_context))
{ {
ClutterOffscreenEffect *offscreen_effect = ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect); CLUTTER_OFFSCREEN_EFFECT (effect);
@ -157,7 +158,8 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect)
} }
static void static void
clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect) clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect); ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

@ -130,7 +130,8 @@ will_have_no_effect (ClutterBrightnessContrastEffect *self)
} }
static gboolean static gboolean
clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect) clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
ClutterEffectClass *parent_class; ClutterEffectClass *parent_class;
@ -156,7 +157,7 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect)
parent_class = parent_class =
CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class); CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class);
if (parent_class->pre_paint (effect)) if (parent_class->pre_paint (effect, paint_context))
{ {
ClutterOffscreenEffect *offscreen_effect = ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect); CLUTTER_OFFSCREEN_EFFECT (effect);
@ -175,7 +176,8 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect)
} }
static void static void
clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect) clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

@ -328,9 +328,10 @@ clutter_canvas_init (ClutterCanvas *self)
} }
static void static void
clutter_canvas_paint_content (ClutterContent *content, clutter_canvas_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *root) ClutterPaintNode *root,
ClutterPaintContext *paint_context)
{ {
ClutterCanvas *self = CLUTTER_CANVAS (content); ClutterCanvas *self = CLUTTER_CANVAS (content);
ClutterCanvasPrivate *priv = self->priv; ClutterCanvasPrivate *priv = self->priv;

View File

@ -152,7 +152,8 @@ clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
} }
static void static void
clutter_clone_paint (ClutterActor *actor) clutter_clone_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
ClutterClone *self = CLUTTER_CLONE (actor); ClutterClone *self = CLUTTER_CLONE (actor);
ClutterClonePrivate *priv = self->priv; ClutterClonePrivate *priv = self->priv;
@ -189,7 +190,7 @@ clutter_clone_paint (ClutterActor *actor)
if (clutter_actor_is_realized (priv->clone_source)) if (clutter_actor_is_realized (priv->clone_source))
{ {
_clutter_actor_push_clone_paint (); _clutter_actor_push_clone_paint ();
clutter_actor_paint (priv->clone_source); clutter_actor_paint (priv->clone_source, paint_context);
_clutter_actor_pop_clone_paint (); _clutter_actor_pop_clone_paint ();
} }

View File

@ -105,7 +105,8 @@ G_DEFINE_TYPE (ClutterColorizeEffect,
CLUTTER_TYPE_OFFSCREEN_EFFECT); CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean static gboolean
clutter_colorize_effect_pre_paint (ClutterEffect *effect) clutter_colorize_effect_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
ClutterEffectClass *parent_class; ClutterEffectClass *parent_class;
@ -126,7 +127,7 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect)
} }
parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class); parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class);
if (parent_class->pre_paint (effect)) if (parent_class->pre_paint (effect, paint_context))
{ {
ClutterOffscreenEffect *offscreen_effect = ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect); CLUTTER_OFFSCREEN_EFFECT (effect);
@ -145,7 +146,8 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect)
} }
static void static void
clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect) clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

@ -34,9 +34,10 @@ void _clutter_content_attached (ClutterContent *conte
void _clutter_content_detached (ClutterContent *content, void _clutter_content_detached (ClutterContent *content,
ClutterActor *actor); ClutterActor *actor);
void _clutter_content_paint_content (ClutterContent *content, void _clutter_content_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *node); ClutterPaintNode *node,
ClutterPaintContext *paint_context);
G_END_DECLS G_END_DECLS

View File

@ -96,9 +96,10 @@ clutter_content_real_invalidate_size (ClutterContent *content)
} }
static void static void
clutter_content_real_paint_content (ClutterContent *content, clutter_content_real_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *context) ClutterPaintNode *context,
ClutterPaintContext *paint_context)
{ {
} }
@ -300,7 +301,8 @@ _clutter_content_detached (ClutterContent *content,
* _clutter_content_paint_content: * _clutter_content_paint_content:
* @content: a #ClutterContent * @content: a #ClutterContent
* @actor: a #ClutterActor * @actor: a #ClutterActor
* @context: a #ClutterPaintNode * @node: a #ClutterPaintNode
* @paint_context: a #ClutterPaintContext
* *
* Creates the render tree for the @content and @actor. * Creates the render tree for the @content and @actor.
* *
@ -308,11 +310,13 @@ _clutter_content_detached (ClutterContent *content,
* virtual function. * virtual function.
*/ */
void void
_clutter_content_paint_content (ClutterContent *content, _clutter_content_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *node) ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node); CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node,
paint_context);
} }
/** /**

View File

@ -65,9 +65,10 @@ struct _ClutterContentInterface
gboolean (* get_preferred_size) (ClutterContent *content, gboolean (* get_preferred_size) (ClutterContent *content,
gfloat *width, gfloat *width,
gfloat *height); gfloat *height);
void (* paint_content) (ClutterContent *content, void (* paint_content) (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *node); ClutterPaintNode *node,
ClutterPaintContext *paint_context);
void (* attached) (ClutterContent *content, void (* attached) (ClutterContent *content,
ClutterActor *actor); ClutterActor *actor);

View File

@ -166,7 +166,8 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
} }
static void static void
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect) clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect); ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
ClutterDeformEffectPrivate *priv = self->priv; ClutterDeformEffectPrivate *priv = self->priv;

View File

@ -112,7 +112,8 @@ G_DEFINE_TYPE (ClutterDesaturateEffect,
CLUTTER_TYPE_OFFSCREEN_EFFECT); CLUTTER_TYPE_OFFSCREEN_EFFECT);
static gboolean static gboolean
clutter_desaturate_effect_pre_paint (ClutterEffect *effect) clutter_desaturate_effect_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect); ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect);
ClutterEffectClass *parent_class; ClutterEffectClass *parent_class;
@ -133,7 +134,7 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect)
} }
parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class); parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class);
if (parent_class->pre_paint (effect)) if (parent_class->pre_paint (effect, paint_context))
{ {
ClutterOffscreenEffect *offscreen_effect = ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect); CLUTTER_OFFSCREEN_EFFECT (effect);
@ -152,7 +153,8 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect)
} }
static void static void
clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect) clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect); ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

@ -5,12 +5,15 @@
G_BEGIN_DECLS G_BEGIN_DECLS
gboolean _clutter_effect_pre_paint (ClutterEffect *effect); gboolean _clutter_effect_pre_paint (ClutterEffect *effect,
void _clutter_effect_post_paint (ClutterEffect *effect); ClutterPaintContext *paint_context);
void _clutter_effect_post_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context);
gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect, gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume); ClutterPaintVolume *volume);
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect); gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
void _clutter_effect_paint (ClutterEffect *effect, void _clutter_effect_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags); ClutterEffectPaintFlags flags);
void _clutter_effect_pick (ClutterEffect *effect); void _clutter_effect_pick (ClutterEffect *effect);

View File

@ -177,13 +177,15 @@ G_DEFINE_ABSTRACT_TYPE (ClutterEffect,
CLUTTER_TYPE_ACTOR_META); CLUTTER_TYPE_ACTOR_META);
static gboolean static gboolean
clutter_effect_real_pre_paint (ClutterEffect *effect) clutter_effect_real_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
return TRUE; return TRUE;
} }
static void static void
clutter_effect_real_post_paint (ClutterEffect *effect) clutter_effect_real_post_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
} }
@ -196,6 +198,7 @@ clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
static void static void
clutter_effect_real_paint (ClutterEffect *effect, clutter_effect_real_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags) ClutterEffectPaintFlags flags)
{ {
ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect); ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect);
@ -206,13 +209,13 @@ clutter_effect_real_paint (ClutterEffect *effect,
effects that haven't migrated to use the 'paint' virtual yet. This effects that haven't migrated to use the 'paint' virtual yet. This
just calls the old pre and post virtuals before chaining on */ just calls the old pre and post virtuals before chaining on */
pre_paint_succeeded = _clutter_effect_pre_paint (effect); pre_paint_succeeded = _clutter_effect_pre_paint (effect, paint_context);
actor = clutter_actor_meta_get_actor (actor_meta); actor = clutter_actor_meta_get_actor (actor_meta);
clutter_actor_continue_paint (actor); clutter_actor_continue_paint (actor, paint_context);
if (pre_paint_succeeded) if (pre_paint_succeeded)
_clutter_effect_post_paint (effect); _clutter_effect_post_paint (effect, paint_context);
} }
static void static void
@ -262,28 +265,31 @@ clutter_effect_init (ClutterEffect *self)
} }
gboolean gboolean
_clutter_effect_pre_paint (ClutterEffect *effect) _clutter_effect_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE); g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect); return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect, paint_context);
} }
void void
_clutter_effect_post_paint (ClutterEffect *effect) _clutter_effect_post_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
g_return_if_fail (CLUTTER_IS_EFFECT (effect)); g_return_if_fail (CLUTTER_IS_EFFECT (effect));
CLUTTER_EFFECT_GET_CLASS (effect)->post_paint (effect); CLUTTER_EFFECT_GET_CLASS (effect)->post_paint (effect, paint_context);
} }
void void
_clutter_effect_paint (ClutterEffect *effect, _clutter_effect_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags) ClutterEffectPaintFlags flags)
{ {
g_return_if_fail (CLUTTER_IS_EFFECT (effect)); g_return_if_fail (CLUTTER_IS_EFFECT (effect));
CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, flags); CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, paint_context, flags);
} }
void void

View File

@ -30,6 +30,7 @@
#endif #endif
#include <clutter/clutter-actor-meta.h> #include <clutter/clutter-actor-meta.h>
#include <clutter/clutter-paint-context.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -74,13 +75,16 @@ struct _ClutterEffectClass
ClutterActorMetaClass parent_class; ClutterActorMetaClass parent_class;
/*< public >*/ /*< public >*/
gboolean (* pre_paint) (ClutterEffect *effect); gboolean (* pre_paint) (ClutterEffect *effect,
void (* post_paint) (ClutterEffect *effect); ClutterPaintContext *paint_context);
void (* post_paint) (ClutterEffect *effect,
ClutterPaintContext *paint_context);
gboolean (* modify_paint_volume) (ClutterEffect *effect, gboolean (* modify_paint_volume) (ClutterEffect *effect,
ClutterPaintVolume *volume); ClutterPaintVolume *volume);
void (* paint) (ClutterEffect *effect, void (* paint) (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags); ClutterEffectPaintFlags flags);
void (* pick) (ClutterEffect *effect); void (* pick) (ClutterEffect *effect);

View File

@ -118,9 +118,10 @@ clutter_image_init (ClutterImage *self)
} }
static void static void
clutter_image_paint_content (ClutterContent *content, clutter_image_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *root) ClutterPaintNode *root,
ClutterPaintContext *paint_context)
{ {
ClutterImagePrivate *priv = CLUTTER_IMAGE (content)->priv; ClutterImagePrivate *priv = CLUTTER_IMAGE (content)->priv;
ClutterPaintNode *node; ClutterPaintNode *node;

View File

@ -237,7 +237,8 @@ update_fbo (ClutterEffect *effect,
} }
static gboolean static gboolean
clutter_offscreen_effect_pre_paint (ClutterEffect *effect) clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
ClutterOffscreenEffectPrivate *priv = self->priv; ClutterOffscreenEffectPrivate *priv = self->priv;
@ -378,7 +379,8 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect)
} }
static void static void
clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect) clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterOffscreenEffectPrivate *priv = effect->priv; ClutterOffscreenEffectPrivate *priv = effect->priv;
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
@ -407,7 +409,8 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect)
} }
static void static void
clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect) clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterOffscreenEffectPrivate *priv = effect->priv; ClutterOffscreenEffectPrivate *priv = effect->priv;
CoglMatrix modelview; CoglMatrix modelview;
@ -436,13 +439,14 @@ clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect)
/* paint the target material; this is virtualized for /* paint the target material; this is virtualized for
* sub-classes that require special hand-holding * sub-classes that require special hand-holding
*/ */
clutter_offscreen_effect_paint_target (effect); clutter_offscreen_effect_paint_target (effect, paint_context);
cogl_pop_matrix (); cogl_pop_matrix ();
} }
static void static void
clutter_offscreen_effect_post_paint (ClutterEffect *effect) clutter_offscreen_effect_post_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
ClutterOffscreenEffectPrivate *priv = self->priv; ClutterOffscreenEffectPrivate *priv = self->priv;
@ -458,11 +462,12 @@ clutter_offscreen_effect_post_paint (ClutterEffect *effect)
cogl_pop_matrix (); cogl_pop_matrix ();
cogl_pop_framebuffer (); cogl_pop_framebuffer ();
clutter_offscreen_effect_paint_texture (self); clutter_offscreen_effect_paint_texture (self, paint_context);
} }
static void static void
clutter_offscreen_effect_paint (ClutterEffect *effect, clutter_offscreen_effect_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags) ClutterEffectPaintFlags flags)
{ {
ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
@ -476,10 +481,10 @@ clutter_offscreen_effect_paint (ClutterEffect *effect,
/* Chain up to the parent paint method which will call the pre and /* Chain up to the parent paint method which will call the pre and
post paint functions to update the image */ post paint functions to update the image */
CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class)-> CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class)->
paint (effect, flags); paint (effect, paint_context, flags);
} }
else else
clutter_offscreen_effect_paint_texture (self); clutter_offscreen_effect_paint_texture (self, paint_context);
} }
static void static void
@ -582,17 +587,20 @@ clutter_offscreen_effect_get_target (ClutterOffscreenEffect *effect)
/** /**
* clutter_offscreen_effect_paint_target: * clutter_offscreen_effect_paint_target:
* @effect: a #ClutterOffscreenEffect * @effect: a #ClutterOffscreenEffect
* @paint_context: a #ClutterPaintContext
* *
* Calls the paint_target() virtual function of the @effect * Calls the paint_target() virtual function of the @effect
* *
* Since: 1.4 * Since: 1.4
*/ */
void void
clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect) clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
g_return_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect)); g_return_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect));
CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect); CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect,
paint_context);
} }
/** /**

View File

@ -79,7 +79,8 @@ struct _ClutterOffscreenEffectClass
CoglHandle (* create_texture) (ClutterOffscreenEffect *effect, CoglHandle (* create_texture) (ClutterOffscreenEffect *effect,
gfloat width, gfloat width,
gfloat height); gfloat height);
void (* paint_target) (ClutterOffscreenEffect *effect); void (* paint_target) (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context);
/*< private >*/ /*< private >*/
void (* _clutter_offscreen1) (void); void (* _clutter_offscreen1) (void);
@ -101,7 +102,8 @@ CLUTTER_EXPORT
CoglHandle clutter_offscreen_effect_get_texture (ClutterOffscreenEffect *effect); CoglHandle clutter_offscreen_effect_get_texture (ClutterOffscreenEffect *effect);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect); void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context);
CLUTTER_EXPORT CLUTTER_EXPORT
CoglHandle clutter_offscreen_effect_create_texture (ClutterOffscreenEffect *effect, CoglHandle clutter_offscreen_effect_create_texture (ClutterOffscreenEffect *effect,
gfloat width, gfloat width,

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2019 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLUTTER_PAINT_CONTEXT_PRIVATE_H
#define CLUTTER_PAINT_CONTEXT_PRIVATE_H
#include "clutter-paint-context.h"
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view);
void clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context,
CoglFramebuffer *framebuffer);
void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context);
#endif /* CLUTTER_PAINT_CONTEXT_PRIVATE_H */

View File

@ -0,0 +1,139 @@
/*
* Copyright (C) 2019 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clutter-build-config.h"
#include "clutter-paint-context-private.h"
struct _ClutterPaintContext
{
grefcount ref_count;
GList *framebuffers;
ClutterStageView *view;
};
G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
clutter_paint_context_ref,
clutter_paint_context_unref)
ClutterPaintContext *
clutter_paint_context_new_for_view (ClutterStageView *view)
{
ClutterPaintContext *paint_context;
CoglFramebuffer *framebuffer;
paint_context = g_new0 (ClutterPaintContext, 1);
g_ref_count_init (&paint_context->ref_count);
paint_context->view = view;
framebuffer = clutter_stage_view_get_framebuffer (view);
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
return paint_context;
}
/**
* clutter_paint_context_new_for_framebuffer: (skip)
*/
ClutterPaintContext *
clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer)
{
ClutterPaintContext *paint_context;
paint_context = g_new0 (ClutterPaintContext, 1);
g_ref_count_init (&paint_context->ref_count);
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
return paint_context;
}
ClutterPaintContext *
clutter_paint_context_ref (ClutterPaintContext *paint_context)
{
g_ref_count_inc (&paint_context->ref_count);
return paint_context;
}
static void
clutter_paint_context_dispose (ClutterPaintContext *paint_context)
{
g_list_free_full (paint_context->framebuffers,
cogl_object_unref);
paint_context->framebuffers = NULL;
}
void
clutter_paint_context_unref (ClutterPaintContext *paint_context)
{
if (g_ref_count_dec (&paint_context->ref_count))
{
clutter_paint_context_dispose (paint_context);
g_free (paint_context);
}
}
void
clutter_paint_context_destroy (ClutterPaintContext *paint_context)
{
clutter_paint_context_dispose (paint_context);
clutter_paint_context_unref (paint_context);
}
void
clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context,
CoglFramebuffer *framebuffer)
{
paint_context->framebuffers = g_list_prepend (paint_context->framebuffers,
cogl_object_ref (framebuffer));
}
void
clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context)
{
g_return_if_fail (paint_context->framebuffers);
cogl_object_unref (paint_context->framebuffers->data);
paint_context->framebuffers =
g_list_delete_link (paint_context->framebuffers,
paint_context->framebuffers);
}
/**
* clutter_paint_context_get_framebuffer:
* @paint_context: The #ClutterPaintContext
*
* Returns: (transfer none): The #CoglFramebuffer used for drawing
*/
CoglFramebuffer *
clutter_paint_context_get_framebuffer (ClutterPaintContext *paint_context)
{
g_return_val_if_fail (paint_context->framebuffers, NULL);
return paint_context->framebuffers->data;
}
/**
* clutter_paint_context_get_stage_view: (skip)
*/
ClutterStageView *
clutter_paint_context_get_stage_view (ClutterPaintContext *paint_context)
{
return paint_context->view;
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2019 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLUTTER_PAINT_CONTEXT_H
#define CLUTTER_PAINT_CONTEXT_H
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <glib-object.h>
#include "clutter-macros.h"
#include "clutter-stage-view.h"
typedef struct _ClutterPaintContext ClutterPaintContext;
#define CLUTTER_TYPE_PAINT_CONTEXT (clutter_paint_context_get_type ())
CLUTTER_EXPORT
GType clutter_paint_context_get_type (void);
CLUTTER_EXPORT
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer);
CLUTTER_EXPORT
ClutterPaintContext * clutter_paint_context_ref (ClutterPaintContext *paint_context);
CLUTTER_EXPORT
void clutter_paint_context_unref (ClutterPaintContext *paint_context);
CLUTTER_EXPORT
void clutter_paint_context_destroy (ClutterPaintContext *paint_context);
CLUTTER_EXPORT
CoglFramebuffer * clutter_paint_context_get_framebuffer (ClutterPaintContext *paint_context);
CLUTTER_EXPORT
ClutterStageView * clutter_paint_context_get_stage_view (ClutterPaintContext *paint_context);
#endif /* CLUTTER_PAINT_CONTEXT_H */

View File

@ -27,6 +27,7 @@
#include <glib-object.h> #include <glib-object.h>
#include <json-glib/json-glib.h> #include <json-glib/json-glib.h>
#include <clutter/clutter-paint-context.h>
#include <clutter/clutter-paint-node.h> #include <clutter/clutter-paint-node.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -63,9 +64,12 @@ struct _ClutterPaintNodeClass
void (* finalize) (ClutterPaintNode *node); void (* finalize) (ClutterPaintNode *node);
gboolean (* pre_draw) (ClutterPaintNode *node); gboolean (* pre_draw) (ClutterPaintNode *node,
void (* draw) (ClutterPaintNode *node); ClutterPaintContext *paint_context);
void (* post_draw) (ClutterPaintNode *node); void (* draw) (ClutterPaintNode *node,
ClutterPaintContext *paint_context);
void (* post_draw) (ClutterPaintNode *node,
ClutterPaintContext *paint_context);
JsonNode*(* serialize) (ClutterPaintNode *node); JsonNode*(* serialize) (ClutterPaintNode *node);

View File

@ -202,18 +202,21 @@ clutter_paint_node_real_finalize (ClutterPaintNode *node)
} }
static gboolean static gboolean
clutter_paint_node_real_pre_draw (ClutterPaintNode *node) clutter_paint_node_real_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
return FALSE; return FALSE;
} }
static void static void
clutter_paint_node_real_draw (ClutterPaintNode *node) clutter_paint_node_real_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
} }
static void static void
clutter_paint_node_real_post_draw (ClutterPaintNode *node) clutter_paint_node_real_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
} }
@ -997,29 +1000,30 @@ clutter_paint_node_add_primitive (ClutterPaintNode *node,
* its children, if any. * its children, if any.
*/ */
void void
clutter_paint_node_paint (ClutterPaintNode *node) clutter_paint_node_paint (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node); ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node);
ClutterPaintNode *iter; ClutterPaintNode *iter;
gboolean res; gboolean res;
res = klass->pre_draw (node); res = klass->pre_draw (node, paint_context);
if (res) if (res)
{ {
klass->draw (node); klass->draw (node, paint_context);
} }
for (iter = node->first_child; for (iter = node->first_child;
iter != NULL; iter != NULL;
iter = iter->next_sibling) iter = iter->next_sibling)
{ {
clutter_paint_node_paint (iter); clutter_paint_node_paint (iter, paint_context);
} }
if (res) if (res)
{ {
klass->post_draw (node); klass->post_draw (node, paint_context);
} }
} }

View File

@ -50,7 +50,8 @@ CLUTTER_EXPORT
void clutter_paint_node_unref (ClutterPaintNode *node); void clutter_paint_node_unref (ClutterPaintNode *node);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_paint_node_paint (ClutterPaintNode *node); void clutter_paint_node_paint (ClutterPaintNode *node,
ClutterPaintContext *paint_context);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_paint_node_set_name (ClutterPaintNode *node, void clutter_paint_node_set_name (ClutterPaintNode *node,

View File

@ -103,7 +103,8 @@ struct _ClutterRootNode
G_DEFINE_TYPE (ClutterRootNode, clutter_root_node, CLUTTER_TYPE_PAINT_NODE) G_DEFINE_TYPE (ClutterRootNode, clutter_root_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean static gboolean
clutter_root_node_pre_draw (ClutterPaintNode *node) clutter_root_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterRootNode *rnode = (ClutterRootNode *) node; ClutterRootNode *rnode = (ClutterRootNode *) node;
@ -117,7 +118,8 @@ clutter_root_node_pre_draw (ClutterPaintNode *node)
} }
static void static void
clutter_root_node_post_draw (ClutterPaintNode *node) clutter_root_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
cogl_pop_framebuffer (); cogl_pop_framebuffer ();
} }
@ -201,7 +203,8 @@ struct _ClutterTransformNodeClass
G_DEFINE_TYPE (ClutterTransformNode, clutter_transform_node, CLUTTER_TYPE_PAINT_NODE) G_DEFINE_TYPE (ClutterTransformNode, clutter_transform_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean static gboolean
clutter_transform_node_pre_draw (ClutterPaintNode *node) clutter_transform_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterTransformNode *transform_node = (ClutterTransformNode *) node; ClutterTransformNode *transform_node = (ClutterTransformNode *) node;
CoglFramebuffer *fb = cogl_get_draw_framebuffer (); CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
@ -213,7 +216,8 @@ clutter_transform_node_pre_draw (ClutterPaintNode *node)
} }
static void static void
clutter_transform_node_post_draw (ClutterPaintNode *node) clutter_transform_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
CoglFramebuffer *fb = cogl_get_draw_framebuffer (); CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
@ -278,7 +282,8 @@ struct _ClutterDummyNode
G_DEFINE_TYPE (ClutterDummyNode, clutter_dummy_node, CLUTTER_TYPE_PAINT_NODE) G_DEFINE_TYPE (ClutterDummyNode, clutter_dummy_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean static gboolean
clutter_dummy_node_pre_draw (ClutterPaintNode *node) clutter_dummy_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
return TRUE; return TRUE;
} }
@ -383,7 +388,8 @@ clutter_pipeline_node_finalize (ClutterPaintNode *node)
} }
static gboolean static gboolean
clutter_pipeline_node_pre_draw (ClutterPaintNode *node) clutter_pipeline_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node); ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
@ -398,7 +404,8 @@ clutter_pipeline_node_pre_draw (ClutterPaintNode *node)
} }
static void static void
clutter_pipeline_node_draw (ClutterPaintNode *node) clutter_pipeline_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node); ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
CoglFramebuffer *fb; CoglFramebuffer *fb;
@ -459,7 +466,8 @@ clutter_pipeline_node_draw (ClutterPaintNode *node)
} }
static void static void
clutter_pipeline_node_post_draw (ClutterPaintNode *node) clutter_pipeline_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
cogl_pop_source (); cogl_pop_source ();
} }
@ -780,7 +788,8 @@ clutter_text_node_finalize (ClutterPaintNode *node)
} }
static gboolean static gboolean
clutter_text_node_pre_draw (ClutterPaintNode *node) clutter_text_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node); ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
@ -788,7 +797,8 @@ clutter_text_node_pre_draw (ClutterPaintNode *node)
} }
static void static void
clutter_text_node_draw (ClutterPaintNode *node) clutter_text_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node); ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
PangoRectangle extents; PangoRectangle extents;
@ -974,7 +984,8 @@ struct _ClutterClipNodeClass
G_DEFINE_TYPE (ClutterClipNode, clutter_clip_node, CLUTTER_TYPE_PAINT_NODE) G_DEFINE_TYPE (ClutterClipNode, clutter_clip_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean static gboolean
clutter_clip_node_pre_draw (ClutterPaintNode *node) clutter_clip_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
gboolean retval = FALSE; gboolean retval = FALSE;
CoglFramebuffer *fb; CoglFramebuffer *fb;
@ -1018,7 +1029,8 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node)
} }
static void static void
clutter_clip_node_post_draw (ClutterPaintNode *node) clutter_clip_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
CoglFramebuffer *fb; CoglFramebuffer *fb;
guint i; guint i;
@ -1100,7 +1112,8 @@ struct _ClutterActorNodeClass
G_DEFINE_TYPE (ClutterActorNode, clutter_actor_node, CLUTTER_TYPE_PAINT_NODE) G_DEFINE_TYPE (ClutterActorNode, clutter_actor_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean static gboolean
clutter_actor_node_pre_draw (ClutterPaintNode *node) clutter_actor_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node);
@ -1110,15 +1123,17 @@ clutter_actor_node_pre_draw (ClutterPaintNode *node)
} }
static void static void
clutter_actor_node_draw (ClutterPaintNode *node) clutter_actor_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node);
clutter_actor_continue_paint (actor_node->actor); clutter_actor_continue_paint (actor_node->actor, paint_context);
} }
static void static void
clutter_actor_node_post_draw (ClutterPaintNode *node) clutter_actor_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node);
@ -1217,7 +1232,8 @@ struct _ClutterLayerNodeClass
G_DEFINE_TYPE (ClutterLayerNode, clutter_layer_node, CLUTTER_TYPE_PAINT_NODE) G_DEFINE_TYPE (ClutterLayerNode, clutter_layer_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean static gboolean
clutter_layer_node_pre_draw (ClutterPaintNode *node) clutter_layer_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterLayerNode *lnode = (ClutterLayerNode *) node; ClutterLayerNode *lnode = (ClutterLayerNode *) node;
CoglMatrix matrix; CoglMatrix matrix;
@ -1265,7 +1281,8 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node)
} }
static void static void
clutter_layer_node_post_draw (ClutterPaintNode *node) clutter_layer_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterLayerNode *lnode = CLUTTER_LAYER_NODE (node); ClutterLayerNode *lnode = CLUTTER_LAYER_NODE (node);
CoglFramebuffer *fb; CoglFramebuffer *fb;

View File

@ -395,7 +395,8 @@ clutter_shader_effect_try_static_source (ClutterShaderEffect *self)
} }
static void static void
clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect) clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (effect); ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (effect);
ClutterShaderEffectPrivate *priv = self->priv; ClutterShaderEffectPrivate *priv = self->priv;
@ -425,7 +426,7 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect)
out: out:
/* paint the offscreen buffer */ /* paint the offscreen buffer */
parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_shader_effect_parent_class); parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_shader_effect_parent_class);
parent->paint_target (effect); parent->paint_target (effect, paint_context);
} }

View File

@ -33,5 +33,7 @@ gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
void clutter_stage_view_set_dirty_projection (ClutterStageView *view, void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
gboolean dirty); gboolean dirty);
void clutter_stage_view_add_redraw_clip (ClutterStageView *view,
cairo_rectangle_int_t *clip);
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */ #endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */

View File

@ -68,6 +68,7 @@
#include "clutter-marshal.h" #include "clutter-marshal.h"
#include "clutter-master-clock.h" #include "clutter-master-clock.h"
#include "clutter-mutter.h" #include "clutter-mutter.h"
#include "clutter-paint-context-private.h"
#include "clutter-paint-volume-private.h" #include "clutter-paint-volume-private.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "clutter-stage-manager-private.h" #include "clutter-stage-manager-private.h"
@ -922,8 +923,13 @@ clutter_stage_do_paint_view (ClutterStage *stage,
ClutterStageView *view, ClutterStageView *view,
const cairo_rectangle_int_t *clip) const cairo_rectangle_int_t *clip)
{ {
ClutterPaintContext *paint_context;
paint_context = clutter_paint_context_new_for_view (view);
setup_view_for_pick_or_paint (stage, view, clip); setup_view_for_pick_or_paint (stage, view, clip);
clutter_actor_paint (CLUTTER_ACTOR (stage)); clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
clutter_paint_context_destroy (paint_context);
} }
/* This provides a common point of entry for painting the scenegraph /* This provides a common point of entry for painting the scenegraph
@ -963,14 +969,15 @@ _clutter_stage_emit_after_paint (ClutterStage *stage)
* respect the Z order as it uses our empty sort_depth_order. * respect the Z order as it uses our empty sort_depth_order.
*/ */
static void static void
clutter_stage_paint (ClutterActor *self) clutter_stage_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
ClutterActorIter iter; ClutterActorIter iter;
ClutterActor *child; ClutterActor *child;
clutter_actor_iter_init (&iter, self); clutter_actor_iter_init (&iter, self);
while (clutter_actor_iter_next (&iter, &child)) while (clutter_actor_iter_next (&iter, &child))
clutter_actor_paint (child); clutter_actor_paint (child, paint_context);
} }
static void static void
@ -2165,6 +2172,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
/** /**
* ClutterStage::after-paint: * ClutterStage::after-paint:
* @stage: the stage that received the event * @stage: the stage that received the event
* @paint_Context: the paint context
* *
* The ::after-paint signal is emitted after the stage is painted, * The ::after-paint signal is emitted after the stage is painted,
* but before the results are displayed on the screen. * but before the results are displayed on the screen.

View File

@ -2548,7 +2548,8 @@ clutter_text_compute_layout_offsets (ClutterText *self,
#define TEXT_PADDING 2 #define TEXT_PADDING 2
static void static void
clutter_text_paint (ClutterActor *self) clutter_text_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
ClutterText *text = CLUTTER_TEXT (self); ClutterText *text = CLUTTER_TEXT (self);
ClutterTextPrivate *priv = text->priv; ClutterTextPrivate *priv = text->priv;

View File

@ -277,14 +277,15 @@ clutter_container_iface_init (ClutterContainerIface *iface)
} }
static void static void
clutter_group_real_paint (ClutterActor *actor) clutter_group_real_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
ClutterGroupPrivate *priv = CLUTTER_GROUP (actor)->priv; ClutterGroupPrivate *priv = CLUTTER_GROUP (actor)->priv;
CLUTTER_NOTE (PAINT, "ClutterGroup paint enter '%s'", CLUTTER_NOTE (PAINT, "ClutterGroup paint enter '%s'",
_clutter_actor_get_debug_name (actor)); _clutter_actor_get_debug_name (actor));
g_list_foreach (priv->children, (GFunc) clutter_actor_paint, NULL); g_list_foreach (priv->children, (GFunc) clutter_actor_paint, paint_context);
CLUTTER_NOTE (PAINT, "ClutterGroup paint leave '%s'", CLUTTER_NOTE (PAINT, "ClutterGroup paint leave '%s'",
_clutter_actor_get_debug_name (actor)); _clutter_actor_get_debug_name (actor));

View File

@ -78,7 +78,8 @@ static const ClutterColor default_border_color = { 0, 0, 0, 255 };
G_DEFINE_TYPE_WITH_PRIVATE (ClutterRectangle, clutter_rectangle, CLUTTER_TYPE_ACTOR) G_DEFINE_TYPE_WITH_PRIVATE (ClutterRectangle, clutter_rectangle, CLUTTER_TYPE_ACTOR)
static void static void
clutter_rectangle_paint (ClutterActor *self) clutter_rectangle_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
ClutterRectanglePrivate *priv = CLUTTER_RECTANGLE (self)->priv; ClutterRectanglePrivate *priv = CLUTTER_RECTANGLE (self)->priv;
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

@ -58,6 +58,7 @@ clutter_headers = [
'clutter-mutter.h', 'clutter-mutter.h',
'clutter-offscreen-effect.h', 'clutter-offscreen-effect.h',
'clutter-page-turn-effect.h', 'clutter-page-turn-effect.h',
'clutter-paint-context.h',
'clutter-paint-nodes.h', 'clutter-paint-nodes.h',
'clutter-paint-node.h', 'clutter-paint-node.h',
'clutter-pan-action.h', 'clutter-pan-action.h',
@ -146,6 +147,7 @@ clutter_sources = [
'clutter-master-clock-default.c', 'clutter-master-clock-default.c',
'clutter-offscreen-effect.c', 'clutter-offscreen-effect.c',
'clutter-page-turn-effect.c', 'clutter-page-turn-effect.c',
'clutter-paint-context.c',
'clutter-paint-nodes.c', 'clutter-paint-nodes.c',
'clutter-paint-node.c', 'clutter-paint-node.c',
'clutter-pan-action.c', 'clutter-pan-action.c',
@ -200,6 +202,7 @@ clutter_private_headers = [
'clutter-master-clock.h', 'clutter-master-clock.h',
'clutter-master-clock-default.h', 'clutter-master-clock-default.h',
'clutter-offscreen-effect-private.h', 'clutter-offscreen-effect-private.h',
'clutter-paint-context-private.h',
'clutter-paint-node-private.h', 'clutter-paint-node-private.h',
'clutter-paint-volume-private.h', 'clutter-paint-volume-private.h',
'clutter-private.h', 'clutter-private.h',

View File

@ -191,7 +191,9 @@ test_invalid_texture_layers_with_constant_colors (TestState *state,
} }
static void static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{ {
test_invalid_texture_layers (state, test_invalid_texture_layers (state,
0, 0 /* position */ 0, 0 /* position */

View File

@ -99,7 +99,9 @@ make_texture (guchar ref)
} }
static void static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{ {
CoglHandle tex0, tex1; CoglHandle tex0, tex1;
CoglHandle material; CoglHandle material;

View File

@ -15,7 +15,9 @@ static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
static void static void
on_paint (ClutterActor *actor, void *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
void *state)
{ {
float saved_viewport[4]; float saved_viewport[4];
CoglMatrix saved_projection; CoglMatrix saved_projection;

View File

@ -45,7 +45,9 @@ make_texture (void)
} }
static void static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{ {
CoglHandle tex; CoglHandle tex;
CoglHandle material; CoglHandle material;

View File

@ -140,7 +140,9 @@ check_paint (TestState *state, int x, int y, int scale)
#define FRAME_COUNT_UPDATED 8 #define FRAME_COUNT_UPDATED 8
static void static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{ {
CoglHandle material; CoglHandle material;

View File

@ -96,7 +96,9 @@ validate_result (TestState *state)
} }
static void static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{ {
/* Draw a faded blue triangle */ /* Draw a faded blue triangle */
cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue"); cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue");

View File

@ -63,7 +63,9 @@ validate_result (TestState *state)
} }
static void static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{ {
/* Draw a faded blue triangle */ /* Draw a faded blue triangle */
cogl_vertex_buffer_draw (state->buffer, cogl_vertex_buffer_draw (state->buffer,

View File

@ -66,7 +66,9 @@ assert_rectangle_color_and_black_border (int x,
static void static void
on_paint (ClutterActor *actor, void *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
void *state)
{ {
float saved_viewport[4]; float saved_viewport[4];
CoglMatrix saved_projection; CoglMatrix saved_projection;

View File

@ -184,12 +184,13 @@ notify_watchers_for_mode (MetaStage *stage,
} }
static void static void
meta_stage_paint (ClutterActor *actor) meta_stage_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
MetaStage *stage = META_STAGE (actor); MetaStage *stage = META_STAGE (actor);
GList *l; GList *l;
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor); CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor, paint_context);
notify_watchers_for_mode (stage, stage->current_view, notify_watchers_for_mode (stage, stage->current_view,
META_STAGE_WATCH_AFTER_ACTOR_PAINT); META_STAGE_WATCH_AFTER_ACTOR_PAINT);

View File

@ -507,7 +507,8 @@ meta_background_actor_get_paint_volume (ClutterActor *actor,
} }
static void static void
meta_background_actor_paint (ClutterActor *actor) meta_background_actor_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor); MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
ClutterActorBox actor_box; ClutterActorBox actor_box;

View File

@ -716,9 +716,10 @@ select_texture_for_paint (MetaShapedTexture *stex)
} }
static void static void
meta_shaped_texture_paint_content (ClutterContent *content, meta_shaped_texture_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *root_node) ClutterPaintNode *root_node,
ClutterPaintContext *paint_context)
{ {
MetaShapedTexture *stex = META_SHAPED_TEXTURE (content); MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
ClutterActorBox alloc; ClutterActorBox alloc;
@ -1184,6 +1185,7 @@ get_image_via_offscreen (MetaShapedTexture *stex,
CoglMatrix projection_matrix; CoglMatrix projection_matrix;
cairo_rectangle_int_t fallback_clip; cairo_rectangle_int_t fallback_clip;
ClutterColor clear_color; ClutterColor clear_color;
ClutterPaintContext *paint_context;
cairo_surface_t *surface; cairo_surface_t *surface;
if (!clip) if (!clip)
@ -1234,6 +1236,8 @@ get_image_via_offscreen (MetaShapedTexture *stex,
root_node = clutter_root_node_new (fb, &clear_color, COGL_BUFFER_BIT_COLOR); root_node = clutter_root_node_new (fb, &clear_color, COGL_BUFFER_BIT_COLOR);
clutter_paint_node_set_name (root_node, "MetaShapedTexture.offscreen"); clutter_paint_node_set_name (root_node, "MetaShapedTexture.offscreen");
paint_context = clutter_paint_context_new_for_framebuffer (fb);
do_paint_content (stex, root_node, do_paint_content (stex, root_node,
stex->texture, stex->texture,
&(ClutterActorBox) { &(ClutterActorBox) {
@ -1243,7 +1247,8 @@ get_image_via_offscreen (MetaShapedTexture *stex,
}, },
255); 255);
clutter_paint_node_paint (root_node); clutter_paint_node_paint (root_node, paint_context);
clutter_paint_context_destroy (paint_context);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
clip->width, clip->height); clip->width, clip->height);

View File

@ -99,7 +99,8 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
} }
static void static void
meta_surface_actor_wayland_paint (ClutterActor *actor) meta_surface_actor_wayland_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor); MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
@ -112,7 +113,8 @@ meta_surface_actor_wayland_paint (ClutterActor *actor)
wl_list_init (&self->frame_callback_list); wl_list_init (&self->frame_callback_list);
} }
CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor); CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor,
paint_context);
} }
static void static void

View File

@ -116,7 +116,8 @@ set_clip_region (MetaSurfaceActor *surface_actor,
} }
static void static void
meta_surface_actor_paint (ClutterActor *actor) meta_surface_actor_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (actor); MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (actor);
MetaSurfaceActorPrivate *priv = MetaSurfaceActorPrivate *priv =
@ -125,7 +126,8 @@ meta_surface_actor_paint (ClutterActor *actor)
if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
return; return;
CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->paint (actor); CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->paint (actor,
paint_context);
} }
static void static void

View File

@ -1140,7 +1140,8 @@ meta_window_actor_x11_pre_paint (MetaWindowActor *actor)
} }
static void static void
meta_window_actor_x11_paint (ClutterActor *actor) meta_window_actor_x11_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor);
MetaWindow *window; MetaWindow *window;
@ -1202,7 +1203,8 @@ meta_window_actor_x11_paint (ClutterActor *actor)
cairo_region_destroy (clip); cairo_region_destroy (clip);
} }
CLUTTER_ACTOR_CLASS (meta_window_actor_x11_parent_class)->paint (actor); CLUTTER_ACTOR_CLASS (meta_window_actor_x11_parent_class)->paint (actor,
paint_context);
} }
static void static void

View File

@ -1338,6 +1338,7 @@ meta_window_actor_get_image (MetaWindowActor *self,
CoglColor clear_color; CoglColor clear_color;
float x, y; float x, y;
MetaRectangle scaled_clip; MetaRectangle scaled_clip;
ClutterPaintContext *paint_context;
cairo_surface_t *surface; cairo_surface_t *surface;
if (!priv->surface) if (!priv->surface)
@ -1409,7 +1410,9 @@ meta_window_actor_get_image (MetaWindowActor *self,
cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1); cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
cogl_framebuffer_translate (framebuffer, -x, -y, 0); cogl_framebuffer_translate (framebuffer, -x, -y, 0);
clutter_actor_paint (actor); paint_context = clutter_paint_context_new_for_framebuffer (framebuffer);
clutter_actor_paint (actor, paint_context);
clutter_paint_context_destroy (paint_context);
cogl_pop_framebuffer (); cogl_pop_framebuffer ();

View File

@ -52,7 +52,8 @@ cullable_iface_init (MetaCullableInterface *iface)
} }
static void static void
meta_window_group_paint (ClutterActor *actor) meta_window_group_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
cairo_region_t *clip_region; cairo_region_t *clip_region;
cairo_region_t *unobscured_region; cairo_region_t *unobscured_region;
@ -90,7 +91,8 @@ meta_window_group_paint (ClutterActor *actor)
&paint_y_origin) || &paint_y_origin) ||
!meta_actor_is_untransformed (actor, NULL, NULL)) !meta_actor_is_untransformed (actor, NULL, NULL))
{ {
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor,
paint_context);
return; return;
} }
} }
@ -121,7 +123,8 @@ meta_window_group_paint (ClutterActor *actor)
cairo_region_destroy (unobscured_region); cairo_region_destroy (unobscured_region);
cairo_region_destroy (clip_region); cairo_region_destroy (clip_region);
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor,
paint_context);
meta_cullable_reset_culling (META_CULLABLE (window_group)); meta_cullable_reset_culling (META_CULLABLE (window_group));
} }

View File

@ -37,7 +37,8 @@ G_DEFINE_TYPE (FooActor, foo_actor, CLUTTER_TYPE_ACTOR);
static gboolean group_has_overlaps; static gboolean group_has_overlaps;
static void static void
foo_actor_paint (ClutterActor *actor) foo_actor_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
FooActor *foo_actor = (FooActor *) actor; FooActor *foo_actor = (FooActor *) actor;
ClutterActorBox allocation; ClutterActorBox allocation;

View File

@ -36,7 +36,8 @@ G_DEFINE_TYPE (FooOldShaderEffect,
CLUTTER_TYPE_SHADER_EFFECT); CLUTTER_TYPE_SHADER_EFFECT);
static void static void
foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect) foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect), clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect),
old_shader_effect_source); old_shader_effect_source);
@ -46,7 +47,7 @@ foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect)
1.0f, 0.0f, 0.0f); 1.0f, 0.0f, 0.0f);
CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)-> CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)->
paint_target (effect); paint_target (effect, paint_context);
} }
static void static void
@ -110,7 +111,8 @@ foo_new_shader_effect_get_static_source (ClutterShaderEffect *effect)
} }
static void static void
foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect) foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{ {
clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect), clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect),
"override_color", "override_color",
@ -118,7 +120,7 @@ foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect)
0.0f, 1.0f, 0.0f); 0.0f, 1.0f, 0.0f);
CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)-> CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)->
paint_target (effect); paint_target (effect, paint_context);
} }
static void static void

View File

@ -132,7 +132,8 @@ key_group_key_press (ClutterActor *actor,
} }
static void static void
key_group_paint (ClutterActor *actor) key_group_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
KeyGroup *self = KEY_GROUP (actor); KeyGroup *self = KEY_GROUP (actor);
ClutterActorIter iter; ClutterActorIter iter;
@ -158,7 +159,7 @@ key_group_paint (ClutterActor *actor)
cogl_rectangle (box.x1, box.y1, box.x2, box.y2); cogl_rectangle (box.x1, box.y1, box.x2, box.y2);
} }
clutter_actor_paint (child); clutter_actor_paint (child, paint_context);
} }
} }

View File

@ -28,7 +28,9 @@ struct _CallbackData
}; };
static void static void
on_paint (ClutterActor *stage, CallbackData *data) on_paint (ClutterActor *stage,
ClutterPaintContext *paint_context,
CallbackData *data)
{ {
PangoLayout *new_layout; PangoLayout *new_layout;

View File

@ -150,7 +150,8 @@ key_group_key_press (ClutterActor *actor,
} }
static void static void
key_group_paint (ClutterActor *actor) key_group_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{ {
KeyGroup *self = KEY_GROUP (actor); KeyGroup *self = KEY_GROUP (actor);
ClutterActorIter iter; ClutterActorIter iter;
@ -176,7 +177,7 @@ key_group_paint (ClutterActor *actor)
cogl_rectangle (box.x1, box.y1, box.x2, box.y2); cogl_rectangle (box.x1, box.y1, box.x2, box.y2);
} }
clutter_actor_paint (child); clutter_actor_paint (child, paint_context);
i += 1; i += 1;
} }

View File

@ -55,7 +55,9 @@ frame_cb (ClutterTimeline *timeline,
} }
static void static void
material_rectangle_paint (ClutterActor *actor, gpointer data) material_rectangle_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
gpointer data)
{ {
TestMultiLayerMaterialState *state = data; TestMultiLayerMaterialState *state = data;

View File

@ -83,7 +83,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
*--------------------------------------------------*/ *--------------------------------------------------*/
static void static void
test_coglbox_paint (ClutterActor *self) test_coglbox_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
gfloat texcoords[4] = { 0, 0, 1, 1 }; gfloat texcoords[4] = { 0, 0, 1, 1 };

View File

@ -95,7 +95,9 @@ generate_round_texture (void)
} }
static void static void
paint_cb (ClutterActor *stage, Data *data) paint_cb (ClutterActor *stage,
ClutterPaintContext *paint_context,
Data *data)
{ {
CoglMatrix old_matrix, new_matrix; CoglMatrix old_matrix, new_matrix;
int i; int i;

View File

@ -82,7 +82,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
*--------------------------------------------------*/ *--------------------------------------------------*/
static void static void
test_coglbox_paint(ClutterActor *self) test_coglbox_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
gfloat texcoords[4] = { 0.0, 0.0, 1.0, 1.0 }; gfloat texcoords[4] = { 0.0, 0.0, 1.0, 1.0 };

View File

@ -166,7 +166,8 @@ test_coglbox_triangle_texture (int tex_width,
} }
static void static void
test_coglbox_paint (ClutterActor *self) test_coglbox_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
CoglHandle tex_handle = priv->use_sliced ? priv->sliced_tex CoglHandle tex_handle = priv->use_sliced ? priv->sliced_tex

View File

@ -83,7 +83,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
*--------------------------------------------------*/ *--------------------------------------------------*/
static void static void
test_coglbox_paint (ClutterActor *self) test_coglbox_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{ {
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
gfloat texcoords[4] = { 0.0f, 0.0f, 1.0f, 1.0f }; gfloat texcoords[4] = { 0.0f, 0.0f, 1.0f, 1.0f };

View File

@ -145,7 +145,9 @@ frame_cb (ClutterTimeline *timeline,
} }
static void static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{ {
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
cogl_vertex_buffer_draw_elements (state->buffer, cogl_vertex_buffer_draw_elements (state->buffer,

View File

@ -32,9 +32,10 @@ G_DEFINE_TYPE_WITH_CODE (ColorContent, color_content, G_TYPE_OBJECT,
clutter_content_iface_init)) clutter_content_iface_init))
static void static void
color_content_paint_content (ClutterContent *content, color_content_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *root) ClutterPaintNode *root,
ClutterPaintContext *paint_context)
{ {
ColorContent *self = (ColorContent *) content; ColorContent *self = (ColorContent *) content;
ClutterActorBox box, content_box; ClutterActorBox box, content_box;

View File

@ -33,9 +33,10 @@ G_DEFINE_TYPE_WITH_CODE (SolidContent, solid_content, G_TYPE_OBJECT,
clutter_content_iface_init)) clutter_content_iface_init))
static void static void
solid_content_paint_content (ClutterContent *content, solid_content_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *root) ClutterPaintNode *root,
ClutterPaintContext *paint_context)
{ {
SolidContent *self = (SolidContent *) content; SolidContent *self = (SolidContent *) content;
ClutterActorBox box, content_box; ClutterActorBox box, content_box;

View File

@ -144,8 +144,9 @@ frame_cb (ClutterTimeline *timeline,
} }
static void static void
hand_pre_paint (ClutterActor *actor, hand_pre_paint (ClutterActor *actor,
gpointer user_data) ClutterPaintContext *paint_context,
gpointer user_data)
{ {
SuperOH *oh = user_data; SuperOH *oh = user_data;
gfloat w, h; gfloat w, h;
@ -165,8 +166,9 @@ hand_pre_paint (ClutterActor *actor,
} }
static void static void
hand_post_paint (ClutterActor *actor, hand_post_paint (ClutterActor *actor,
gpointer user_data) ClutterPaintContext *paint_context,
gpointer user_data)
{ {
SuperOH *oh = user_data; SuperOH *oh = user_data;
gfloat w, h; gfloat w, h;

View File

@ -98,7 +98,9 @@ TestCallback tests[] =
}; };
static void static void
on_paint (ClutterActor *actor, TestState *state) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{ {
tests[state->current_test] (state); tests[state->current_test] (state);
} }

View File

@ -54,7 +54,9 @@ do_events (ClutterActor *stage)
} }
static void static void
on_paint (ClutterActor *stage, gconstpointer *data) on_paint (ClutterActor *stage,
ClutterPaintContext *paint_context,
gconstpointer *data)
{ {
do_events (stage); do_events (stage);
} }

View File

@ -11,7 +11,9 @@ static int n_chars;
static int rows, cols; static int rows, cols;
static void static void
on_paint (ClutterActor *actor, gconstpointer *data) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
gconstpointer *data)
{ {
static GTimer *timer = NULL; static GTimer *timer = NULL;
static int fps = 0; static int fps = 0;

View File

@ -10,7 +10,9 @@
#define ROWS 20 #define ROWS 20
static void static void
on_paint (ClutterActor *actor, gconstpointer *data) on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
gconstpointer *data)
{ {
static GTimer *timer = NULL; static GTimer *timer = NULL;
static int fps = 0; static int fps = 0;

View File

@ -25,7 +25,9 @@ clutter_perf_fps_init (void)
g_random_set_seed (12345678); g_random_set_seed (12345678);
} }
static void perf_stage_paint_cb (ClutterStage *stage, gpointer *data); static void perf_stage_paint_cb (ClutterStage *stage,
ClutterPaintContext *paint_context,
gpointer *data);
static gboolean perf_fake_mouse_cb (gpointer stage); static gboolean perf_fake_mouse_cb (gpointer stage);
static inline void static inline void
@ -47,7 +49,10 @@ clutter_perf_fps_report (const gchar *id)
id, testframes / g_timer_elapsed (testtimer, NULL)); id, testframes / g_timer_elapsed (testtimer, NULL));
} }
static void perf_stage_paint_cb (ClutterStage *stage, gpointer *data) static void
perf_stage_paint_cb (ClutterStage *stage,
ClutterPaintContext *paint_context,
gpointer *data)
{ {
if (!testtimer) if (!testtimer)
testtimer = g_timer_new (); testtimer = g_timer_new ();