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
clutter_actor_real_paint (ClutterActor *actor)
clutter_actor_real_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{
ClutterActorPrivate *priv = actor->priv;
ClutterActor *iter;
@ -3777,13 +3778,14 @@ clutter_actor_real_paint (ClutterActor *actor)
iter->priv->allocation.x2 - iter->priv->allocation.x1,
iter->priv->allocation.y2 - iter->priv->allocation.y1);
clutter_actor_paint (iter);
clutter_actor_paint (iter, paint_context);
}
}
static gboolean
clutter_actor_paint_node (ClutterActor *actor,
ClutterPaintNode *root)
clutter_actor_paint_node (ClutterActor *actor,
ClutterPaintNode *root,
ClutterPaintContext *paint_context)
{
ClutterActorPrivate *priv = actor->priv;
ClutterActorBox box;
@ -3847,7 +3849,7 @@ clutter_actor_paint_node (ClutterActor *actor,
}
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)
CLUTTER_ACTOR_GET_CLASS (actor)->paint_node (actor, root);
@ -3863,7 +3865,7 @@ clutter_actor_paint_node (ClutterActor *actor,
}
#endif /* CLUTTER_ENABLE_DEBUG */
clutter_paint_node_paint (root);
clutter_paint_node_paint (root, paint_context);
return TRUE;
}
@ -3887,7 +3889,8 @@ clutter_actor_paint_node (ClutterActor *actor,
* unless it is performing a pick paint.
*/
void
clutter_actor_paint (ClutterActor *self)
clutter_actor_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{
g_autoptr (ClutterPaintNode) actor_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))
_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
paint run including all the effects so it's no longer dirty */
@ -4089,7 +4092,8 @@ clutter_actor_paint (ClutterActor *self)
* Since: 1.8
*/
void
clutter_actor_continue_paint (ClutterActor *self)
clutter_actor_continue_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{
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
* 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);
/* XXX:2.0 - Call the paint() virtual directly */
if (g_signal_has_handler_pending (self, actor_signals[PAINT],
0, TRUE))
g_signal_emit (self, actor_signals[PAINT], 0);
g_signal_emit (self, actor_signals[PAINT], 0, paint_context);
else
CLUTTER_ACTOR_GET_CLASS (self)->paint (self);
CLUTTER_ACTOR_GET_CLASS (self)->paint (self, paint_context);
}
else
{
@ -4157,7 +4161,7 @@ clutter_actor_continue_paint (ClutterActor *self)
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;
}
@ -8534,6 +8538,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
/**
* ClutterActor::paint:
* @actor: the #ClutterActor that received the signal
* @paint_context: a #ClutterPaintContext
*
* 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_STRUCT_OFFSET (ClutterActorClass, paint),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
G_TYPE_NONE, 1,
CLUTTER_TYPE_PAINT_CONTEXT);
/**
* ClutterActor::realize:
* @actor: the #ClutterActor that received the signal

View File

@ -39,6 +39,7 @@
#include <clutter/clutter-types.h>
#include <clutter/clutter-event.h>
#include <clutter/clutter-paint-context.h>
G_BEGIN_DECLS
@ -228,7 +229,8 @@ struct _ClutterActorClass
void (* unrealize) (ClutterActor *self);
void (* map) (ClutterActor *self);
void (* unmap) (ClutterActor *self);
void (* paint) (ClutterActor *self);
void (* paint) (ClutterActor *self,
ClutterPaintContext *paint_context);
void (* parent_set) (ClutterActor *actor,
ClutterActor *old_parent);
@ -349,9 +351,11 @@ void clutter_actor_map
CLUTTER_EXPORT
void clutter_actor_unmap (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_paint (ClutterActor *self);
void clutter_actor_paint (ClutterActor *self,
ClutterPaintContext *paint_context);
CLUTTER_EXPORT
void clutter_actor_continue_paint (ClutterActor *self);
void clutter_actor_continue_paint (ClutterActor *self,
ClutterPaintContext *paint_context);
CLUTTER_EXPORT
void clutter_actor_pick (ClutterActor *actor);
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 (ClutterMargin, clutter_margin_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 (ClutterPaintVolume, clutter_paint_volume_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);
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);
ClutterEffectClass *parent_class;
@ -124,7 +125,7 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect)
}
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 =
CLUTTER_OFFSCREEN_EFFECT (effect);
@ -157,7 +158,8 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect)
}
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);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

@ -130,7 +130,8 @@ will_have_no_effect (ClutterBrightnessContrastEffect *self)
}
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);
ClutterEffectClass *parent_class;
@ -156,7 +157,7 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *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 =
CLUTTER_OFFSCREEN_EFFECT (effect);
@ -175,7 +176,8 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect)
}
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);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

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

View File

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

View File

@ -105,7 +105,8 @@ G_DEFINE_TYPE (ClutterColorizeEffect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
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);
ClutterEffectClass *parent_class;
@ -126,7 +127,7 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect)
}
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 =
CLUTTER_OFFSCREEN_EFFECT (effect);
@ -145,7 +146,8 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect)
}
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);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

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

View File

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

View File

@ -166,7 +166,8 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
}
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);
ClutterDeformEffectPrivate *priv = self->priv;

View File

@ -112,7 +112,8 @@ G_DEFINE_TYPE (ClutterDesaturateEffect,
CLUTTER_TYPE_OFFSCREEN_EFFECT);
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);
ClutterEffectClass *parent_class;
@ -133,7 +134,7 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect)
}
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 =
CLUTTER_OFFSCREEN_EFFECT (effect);
@ -152,7 +153,8 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect)
}
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);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

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

View File

@ -177,13 +177,15 @@ G_DEFINE_ABSTRACT_TYPE (ClutterEffect,
CLUTTER_TYPE_ACTOR_META);
static gboolean
clutter_effect_real_pre_paint (ClutterEffect *effect)
clutter_effect_real_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{
return TRUE;
}
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
clutter_effect_real_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags)
{
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
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);
clutter_actor_continue_paint (actor);
clutter_actor_continue_paint (actor, paint_context);
if (pre_paint_succeeded)
_clutter_effect_post_paint (effect);
_clutter_effect_post_paint (effect, paint_context);
}
static void
@ -262,28 +265,31 @@ clutter_effect_init (ClutterEffect *self)
}
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);
return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect);
return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect, paint_context);
}
void
_clutter_effect_post_paint (ClutterEffect *effect)
_clutter_effect_post_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{
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
_clutter_effect_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags)
{
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

View File

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

View File

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

View File

@ -237,7 +237,8 @@ update_fbo (ClutterEffect *effect,
}
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);
ClutterOffscreenEffectPrivate *priv = self->priv;
@ -378,7 +379,8 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect)
}
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;
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
@ -407,7 +409,8 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect)
}
static void
clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect)
clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context)
{
ClutterOffscreenEffectPrivate *priv = effect->priv;
CoglMatrix modelview;
@ -436,13 +439,14 @@ clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect)
/* paint the target material; this is virtualized for
* sub-classes that require special hand-holding
*/
clutter_offscreen_effect_paint_target (effect);
clutter_offscreen_effect_paint_target (effect, paint_context);
cogl_pop_matrix ();
}
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);
ClutterOffscreenEffectPrivate *priv = self->priv;
@ -458,11 +462,12 @@ clutter_offscreen_effect_post_paint (ClutterEffect *effect)
cogl_pop_matrix ();
cogl_pop_framebuffer ();
clutter_offscreen_effect_paint_texture (self);
clutter_offscreen_effect_paint_texture (self, paint_context);
}
static void
clutter_offscreen_effect_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags)
{
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
post paint functions to update the image */
CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class)->
paint (effect, flags);
paint (effect, paint_context, flags);
}
else
clutter_offscreen_effect_paint_texture (self);
clutter_offscreen_effect_paint_texture (self, paint_context);
}
static void
@ -582,17 +587,20 @@ clutter_offscreen_effect_get_target (ClutterOffscreenEffect *effect)
/**
* clutter_offscreen_effect_paint_target:
* @effect: a #ClutterOffscreenEffect
* @paint_context: a #ClutterPaintContext
*
* Calls the paint_target() virtual function of the @effect
*
* Since: 1.4
*/
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));
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,
gfloat width,
gfloat height);
void (* paint_target) (ClutterOffscreenEffect *effect);
void (* paint_target) (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context);
/*< private >*/
void (* _clutter_offscreen1) (void);
@ -101,7 +102,8 @@ CLUTTER_EXPORT
CoglHandle clutter_offscreen_effect_get_texture (ClutterOffscreenEffect *effect);
CLUTTER_EXPORT
void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect);
void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context);
CLUTTER_EXPORT
CoglHandle clutter_offscreen_effect_create_texture (ClutterOffscreenEffect *effect,
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 <json-glib/json-glib.h>
#include <clutter/clutter-paint-context.h>
#include <clutter/clutter-paint-node.h>
G_BEGIN_DECLS
@ -63,9 +64,12 @@ struct _ClutterPaintNodeClass
void (* finalize) (ClutterPaintNode *node);
gboolean (* pre_draw) (ClutterPaintNode *node);
void (* draw) (ClutterPaintNode *node);
void (* post_draw) (ClutterPaintNode *node);
gboolean (* pre_draw) (ClutterPaintNode *node,
ClutterPaintContext *paint_context);
void (* draw) (ClutterPaintNode *node,
ClutterPaintContext *paint_context);
void (* post_draw) (ClutterPaintNode *node,
ClutterPaintContext *paint_context);
JsonNode*(* serialize) (ClutterPaintNode *node);

View File

@ -202,18 +202,21 @@ clutter_paint_node_real_finalize (ClutterPaintNode *node)
}
static gboolean
clutter_paint_node_real_pre_draw (ClutterPaintNode *node)
clutter_paint_node_real_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
return FALSE;
}
static void
clutter_paint_node_real_draw (ClutterPaintNode *node)
clutter_paint_node_real_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
}
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.
*/
void
clutter_paint_node_paint (ClutterPaintNode *node)
clutter_paint_node_paint (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node);
ClutterPaintNode *iter;
gboolean res;
res = klass->pre_draw (node);
res = klass->pre_draw (node, paint_context);
if (res)
{
klass->draw (node);
klass->draw (node, paint_context);
}
for (iter = node->first_child;
iter != NULL;
iter = iter->next_sibling)
{
clutter_paint_node_paint (iter);
clutter_paint_node_paint (iter, paint_context);
}
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);
CLUTTER_EXPORT
void clutter_paint_node_paint (ClutterPaintNode *node);
void clutter_paint_node_paint (ClutterPaintNode *node,
ClutterPaintContext *paint_context);
CLUTTER_EXPORT
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)
static gboolean
clutter_root_node_pre_draw (ClutterPaintNode *node)
clutter_root_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterRootNode *rnode = (ClutterRootNode *) node;
@ -117,7 +118,8 @@ clutter_root_node_pre_draw (ClutterPaintNode *node)
}
static void
clutter_root_node_post_draw (ClutterPaintNode *node)
clutter_root_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
cogl_pop_framebuffer ();
}
@ -201,7 +203,8 @@ struct _ClutterTransformNodeClass
G_DEFINE_TYPE (ClutterTransformNode, clutter_transform_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean
clutter_transform_node_pre_draw (ClutterPaintNode *node)
clutter_transform_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterTransformNode *transform_node = (ClutterTransformNode *) node;
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
@ -213,7 +216,8 @@ clutter_transform_node_pre_draw (ClutterPaintNode *node)
}
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 ();
@ -278,7 +282,8 @@ struct _ClutterDummyNode
G_DEFINE_TYPE (ClutterDummyNode, clutter_dummy_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean
clutter_dummy_node_pre_draw (ClutterPaintNode *node)
clutter_dummy_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
return TRUE;
}
@ -383,7 +388,8 @@ clutter_pipeline_node_finalize (ClutterPaintNode *node)
}
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);
@ -398,7 +404,8 @@ clutter_pipeline_node_pre_draw (ClutterPaintNode *node)
}
static void
clutter_pipeline_node_draw (ClutterPaintNode *node)
clutter_pipeline_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
CoglFramebuffer *fb;
@ -459,7 +466,8 @@ clutter_pipeline_node_draw (ClutterPaintNode *node)
}
static void
clutter_pipeline_node_post_draw (ClutterPaintNode *node)
clutter_pipeline_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
cogl_pop_source ();
}
@ -780,7 +788,8 @@ clutter_text_node_finalize (ClutterPaintNode *node)
}
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);
@ -788,7 +797,8 @@ clutter_text_node_pre_draw (ClutterPaintNode *node)
}
static void
clutter_text_node_draw (ClutterPaintNode *node)
clutter_text_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
PangoRectangle extents;
@ -974,7 +984,8 @@ struct _ClutterClipNodeClass
G_DEFINE_TYPE (ClutterClipNode, clutter_clip_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean
clutter_clip_node_pre_draw (ClutterPaintNode *node)
clutter_clip_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
gboolean retval = FALSE;
CoglFramebuffer *fb;
@ -1018,7 +1029,8 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node)
}
static void
clutter_clip_node_post_draw (ClutterPaintNode *node)
clutter_clip_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
CoglFramebuffer *fb;
guint i;
@ -1100,7 +1112,8 @@ struct _ClutterActorNodeClass
G_DEFINE_TYPE (ClutterActorNode, clutter_actor_node, CLUTTER_TYPE_PAINT_NODE)
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);
@ -1110,15 +1123,17 @@ clutter_actor_node_pre_draw (ClutterPaintNode *node)
}
static void
clutter_actor_node_draw (ClutterPaintNode *node)
clutter_actor_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
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
clutter_actor_node_post_draw (ClutterPaintNode *node)
clutter_actor_node_post_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node);
@ -1217,7 +1232,8 @@ struct _ClutterLayerNodeClass
G_DEFINE_TYPE (ClutterLayerNode, clutter_layer_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean
clutter_layer_node_pre_draw (ClutterPaintNode *node)
clutter_layer_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterLayerNode *lnode = (ClutterLayerNode *) node;
CoglMatrix matrix;
@ -1265,7 +1281,8 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node)
}
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);
CoglFramebuffer *fb;

View File

@ -395,7 +395,8 @@ clutter_shader_effect_try_static_source (ClutterShaderEffect *self)
}
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);
ClutterShaderEffectPrivate *priv = self->priv;
@ -425,7 +426,7 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect)
out:
/* paint the offscreen buffer */
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,
gboolean dirty);
void clutter_stage_view_add_redraw_clip (ClutterStageView *view,
cairo_rectangle_int_t *clip);
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */

View File

@ -68,6 +68,7 @@
#include "clutter-marshal.h"
#include "clutter-master-clock.h"
#include "clutter-mutter.h"
#include "clutter-paint-context-private.h"
#include "clutter-paint-volume-private.h"
#include "clutter-private.h"
#include "clutter-stage-manager-private.h"
@ -922,8 +923,13 @@ clutter_stage_do_paint_view (ClutterStage *stage,
ClutterStageView *view,
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);
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
@ -963,14 +969,15 @@ _clutter_stage_emit_after_paint (ClutterStage *stage)
* respect the Z order as it uses our empty sort_depth_order.
*/
static void
clutter_stage_paint (ClutterActor *self)
clutter_stage_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{
ClutterActorIter iter;
ClutterActor *child;
clutter_actor_iter_init (&iter, self);
while (clutter_actor_iter_next (&iter, &child))
clutter_actor_paint (child);
clutter_actor_paint (child, paint_context);
}
static void
@ -2165,6 +2172,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
/**
* ClutterStage::after-paint:
* @stage: the stage that received the event
* @paint_Context: the paint context
*
* The ::after-paint signal is emitted after the stage is painted,
* 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
static void
clutter_text_paint (ClutterActor *self)
clutter_text_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{
ClutterText *text = CLUTTER_TEXT (self);
ClutterTextPrivate *priv = text->priv;

View File

@ -277,14 +277,15 @@ clutter_container_iface_init (ClutterContainerIface *iface)
}
static void
clutter_group_real_paint (ClutterActor *actor)
clutter_group_real_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{
ClutterGroupPrivate *priv = CLUTTER_GROUP (actor)->priv;
CLUTTER_NOTE (PAINT, "ClutterGroup paint enter '%s'",
_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_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)
static void
clutter_rectangle_paint (ClutterActor *self)
clutter_rectangle_paint (ClutterActor *self,
ClutterPaintContext *paint_context)
{
ClutterRectanglePrivate *priv = CLUTTER_RECTANGLE (self)->priv;
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -184,12 +184,13 @@ notify_watchers_for_mode (MetaStage *stage,
}
static void
meta_stage_paint (ClutterActor *actor)
meta_stage_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{
MetaStage *stage = META_STAGE (actor);
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,
META_STAGE_WATCH_AFTER_ACTOR_PAINT);

View File

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

View File

@ -716,9 +716,10 @@ select_texture_for_paint (MetaShapedTexture *stex)
}
static void
meta_shaped_texture_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *root_node)
meta_shaped_texture_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *root_node,
ClutterPaintContext *paint_context)
{
MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
ClutterActorBox alloc;
@ -1184,6 +1185,7 @@ get_image_via_offscreen (MetaShapedTexture *stex,
CoglMatrix projection_matrix;
cairo_rectangle_int_t fallback_clip;
ClutterColor clear_color;
ClutterPaintContext *paint_context;
cairo_surface_t *surface;
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);
clutter_paint_node_set_name (root_node, "MetaShapedTexture.offscreen");
paint_context = clutter_paint_context_new_for_framebuffer (fb);
do_paint_content (stex, root_node,
stex->texture,
&(ClutterActorBox) {
@ -1243,7 +1247,8 @@ get_image_via_offscreen (MetaShapedTexture *stex,
},
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,
clip->width, clip->height);

View File

@ -99,7 +99,8 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
}
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);
@ -112,7 +113,8 @@ meta_surface_actor_wayland_paint (ClutterActor *actor)
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

View File

@ -116,7 +116,8 @@ set_clip_region (MetaSurfaceActor *surface_actor,
}
static void
meta_surface_actor_paint (ClutterActor *actor)
meta_surface_actor_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (actor);
MetaSurfaceActorPrivate *priv =
@ -125,7 +126,8 @@ meta_surface_actor_paint (ClutterActor *actor)
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
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

View File

@ -1140,7 +1140,8 @@ meta_window_actor_x11_pre_paint (MetaWindowActor *actor)
}
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);
MetaWindow *window;
@ -1202,7 +1203,8 @@ meta_window_actor_x11_paint (ClutterActor *actor)
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

View File

@ -1338,6 +1338,7 @@ meta_window_actor_get_image (MetaWindowActor *self,
CoglColor clear_color;
float x, y;
MetaRectangle scaled_clip;
ClutterPaintContext *paint_context;
cairo_surface_t *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_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 ();

View File

@ -52,7 +52,8 @@ cullable_iface_init (MetaCullableInterface *iface)
}
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 *unobscured_region;
@ -90,7 +91,8 @@ meta_window_group_paint (ClutterActor *actor)
&paint_y_origin) ||
!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;
}
}
@ -121,7 +123,8 @@ meta_window_group_paint (ClutterActor *actor)
cairo_region_destroy (unobscured_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));
}

View File

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

View File

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

View File

@ -132,7 +132,8 @@ key_group_key_press (ClutterActor *actor,
}
static void
key_group_paint (ClutterActor *actor)
key_group_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{
KeyGroup *self = KEY_GROUP (actor);
ClutterActorIter iter;
@ -158,7 +159,7 @@ key_group_paint (ClutterActor *actor)
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
on_paint (ClutterActor *stage, CallbackData *data)
on_paint (ClutterActor *stage,
ClutterPaintContext *paint_context,
CallbackData *data)
{
PangoLayout *new_layout;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -145,7 +145,9 @@ frame_cb (ClutterTimeline *timeline,
}
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_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))
static void
color_content_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *root)
color_content_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *root,
ClutterPaintContext *paint_context)
{
ColorContent *self = (ColorContent *) content;
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))
static void
solid_content_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *root)
solid_content_paint_content (ClutterContent *content,
ClutterActor *actor,
ClutterPaintNode *root,
ClutterPaintContext *paint_context)
{
SolidContent *self = (SolidContent *) content;
ClutterActorBox box, content_box;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,9 @@ clutter_perf_fps_init (void)
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 inline void
@ -47,7 +49,10 @@ clutter_perf_fps_report (const gchar *id)
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)
testtimer = g_timer_new ();