Compare commits
12 Commits
citadel
...
gbsneto/ef
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4a69e70000 | ||
![]() |
bc81f17d5f | ||
![]() |
3b64f56c5f | ||
![]() |
31dc74dfd3 | ||
![]() |
26a225f675 | ||
![]() |
0caca4fc49 | ||
![]() |
5d11104a0a | ||
![]() |
5186f0e3ef | ||
![]() |
61d247f399 | ||
![]() |
19bf3751eb | ||
![]() |
963df6f61c | ||
![]() |
a510339970 |
@ -3746,7 +3746,7 @@ clutter_actor_paint (ClutterActor *self,
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (self))
|
||||
return;
|
||||
|
||||
actor_node = clutter_actor_node_new (self);
|
||||
actor_node = clutter_actor_node_new (self, -1);
|
||||
root_node = clutter_paint_node_ref (actor_node);
|
||||
|
||||
if (priv->has_clip)
|
||||
|
@ -5,10 +5,6 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
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);
|
||||
|
@ -169,6 +169,8 @@
|
||||
#include "clutter-effect-private.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-paint-node-private.h"
|
||||
#include "clutter-paint-nodes.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-actor-private.h"
|
||||
|
||||
@ -196,26 +198,46 @@ clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_real_paint_node (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags)
|
||||
{
|
||||
ClutterPaintNode *actor_node;
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
|
||||
actor_node = clutter_actor_node_new (actor, -1);
|
||||
clutter_paint_node_add_child (node, actor_node);
|
||||
clutter_paint_node_unref (actor_node);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_real_paint (ClutterEffect *effect,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags)
|
||||
{
|
||||
ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect);
|
||||
ClutterActor *actor;
|
||||
ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect);
|
||||
ClutterPaintNode *node;
|
||||
gboolean pre_paint_succeeded;
|
||||
|
||||
/* The default implementation provides a compatibility wrapper for
|
||||
effects that haven't migrated to use the 'paint' virtual yet. This
|
||||
just calls the old pre and post virtuals before chaining on */
|
||||
|
||||
pre_paint_succeeded = _clutter_effect_pre_paint (effect, paint_context);
|
||||
pre_paint_succeeded = effect_class->pre_paint (effect, paint_context);
|
||||
|
||||
actor = clutter_actor_meta_get_actor (actor_meta);
|
||||
clutter_actor_continue_paint (actor, paint_context);
|
||||
node = clutter_effect_node_new (effect);
|
||||
|
||||
effect_class->paint_node (effect, node, paint_context, flags);
|
||||
clutter_paint_node_paint (node, paint_context);
|
||||
|
||||
if (pre_paint_succeeded)
|
||||
_clutter_effect_post_paint (effect, paint_context);
|
||||
effect_class->post_paint (effect, paint_context);
|
||||
|
||||
clutter_paint_node_unref (node);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -255,6 +277,7 @@ clutter_effect_class_init (ClutterEffectClass *klass)
|
||||
klass->post_paint = clutter_effect_real_post_paint;
|
||||
klass->modify_paint_volume = clutter_effect_real_modify_paint_volume;
|
||||
klass->paint = clutter_effect_real_paint;
|
||||
klass->paint_node = clutter_effect_real_paint_node;
|
||||
klass->pick = clutter_effect_real_pick;
|
||||
}
|
||||
|
||||
@ -263,24 +286,6 @@ clutter_effect_init (ClutterEffect *self)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
_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, paint_context);
|
||||
}
|
||||
|
||||
void
|
||||
_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, paint_context);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_effect_paint (ClutterEffect *effect,
|
||||
ClutterPaintContext *paint_context,
|
||||
|
@ -87,6 +87,10 @@ struct _ClutterEffectClass
|
||||
void (* paint) (ClutterEffect *effect,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* paint_node) (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* pick) (ClutterEffect *effect,
|
||||
ClutterPickContext *pick_context);
|
||||
|
||||
|
@ -272,10 +272,10 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
|
||||
local_offset = GRAPHENE_POINT3D_INIT (0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
|
||||
return FALSE;
|
||||
goto disable_effect;
|
||||
|
||||
if (priv->actor == NULL)
|
||||
return FALSE;
|
||||
goto disable_effect;
|
||||
|
||||
stage = _clutter_actor_get_stage_internal (priv->actor);
|
||||
clutter_actor_get_size (stage, &stage_width, &stage_height);
|
||||
@ -320,7 +320,7 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
|
||||
|
||||
/* First assert that the framebuffer is the right size... */
|
||||
if (!update_fbo (effect, target_width, target_height, resource_scale))
|
||||
return FALSE;
|
||||
goto disable_effect;
|
||||
|
||||
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
|
||||
cogl_framebuffer_get_modelview_matrix (framebuffer, &old_modelview);
|
||||
@ -387,6 +387,10 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
|
||||
clutter_actor_set_opacity_override (priv->actor, 0xff);
|
||||
|
||||
return TRUE;
|
||||
|
||||
disable_effect:
|
||||
cogl_clear_object (&priv->offscreen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -505,17 +509,10 @@ clutter_offscreen_effect_paint (ClutterEffect *effect,
|
||||
*/
|
||||
if (priv->offscreen == NULL || (flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY))
|
||||
{
|
||||
ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect);
|
||||
gboolean pre_paint_succeeded;
|
||||
ClutterEffectClass *parent_class =
|
||||
CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class);
|
||||
|
||||
pre_paint_succeeded = effect_class->pre_paint (effect, paint_context);
|
||||
|
||||
clutter_actor_continue_paint (priv->actor, paint_context);
|
||||
|
||||
if (pre_paint_succeeded)
|
||||
effect_class->post_paint (effect, paint_context);
|
||||
else
|
||||
g_clear_pointer (&priv->offscreen, cogl_object_unref);
|
||||
parent_class->paint (effect, paint_context, flags);
|
||||
}
|
||||
else
|
||||
clutter_offscreen_effect_paint_texture (self, paint_context);
|
||||
|
@ -141,6 +141,26 @@ ClutterPaintNode * clutter_paint_node_get_last_child (Clutter
|
||||
G_GNUC_INTERNAL
|
||||
ClutterPaintNode * clutter_paint_node_get_parent (ClutterPaintNode *node);
|
||||
|
||||
|
||||
#define CLUTTER_TYPE_EFFECT_NODE (clutter_effect_node_get_type ())
|
||||
#define CLUTTER_EFFECT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_EFFECT_NODE, ClutterEffectNode))
|
||||
#define CLUTTER_IS_EFFECT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_EFFECT_NODE))
|
||||
|
||||
/**
|
||||
* ClutterEffectNode:
|
||||
*
|
||||
* The #ClutterEffectNode structure is an opaque
|
||||
* type whose members cannot be directly accessed.
|
||||
*/
|
||||
typedef struct _ClutterEffectNode ClutterEffectNode;
|
||||
typedef struct _ClutterEffectNode ClutterEffectNodeClass;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_effect_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_effect_node_new (ClutterEffect *actor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_PAINT_NODE_PRIVATE_H__ */
|
||||
|
@ -1149,24 +1149,14 @@ _clutter_paint_node_create (GType gtype)
|
||||
return (gpointer) g_type_create_instance (gtype);
|
||||
}
|
||||
|
||||
static ClutterPaintNode *
|
||||
clutter_paint_node_get_root (ClutterPaintNode *node)
|
||||
{
|
||||
ClutterPaintNode *iter;
|
||||
|
||||
iter = node;
|
||||
while (iter != NULL && iter->parent != NULL)
|
||||
iter = iter->parent;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_paint_node_get_framebuffer:
|
||||
* @node: a #ClutterPaintNode
|
||||
*
|
||||
* Retrieves the #CoglFramebuffer that @node will draw
|
||||
* into, if it the root node has a custom framebuffer set.
|
||||
* into. If @node doesn't specify a custom framebuffer,
|
||||
* the first parent node with a custom framebuffer will
|
||||
* be used.
|
||||
*
|
||||
* Returns: (transfer none): a #CoglFramebuffer or %NULL if no custom one is
|
||||
* set.
|
||||
@ -1174,12 +1164,19 @@ clutter_paint_node_get_root (ClutterPaintNode *node)
|
||||
CoglFramebuffer *
|
||||
clutter_paint_node_get_framebuffer (ClutterPaintNode *node)
|
||||
{
|
||||
ClutterPaintNode *root = clutter_paint_node_get_root (node);
|
||||
ClutterPaintNodeClass *klass;
|
||||
ClutterPaintNode *iter;
|
||||
|
||||
iter = node;
|
||||
while (iter != NULL && iter->parent != NULL)
|
||||
{
|
||||
klass = CLUTTER_PAINT_NODE_GET_CLASS (iter);
|
||||
|
||||
klass = CLUTTER_PAINT_NODE_GET_CLASS (root);
|
||||
if (klass->get_framebuffer != NULL)
|
||||
return klass->get_framebuffer (root);
|
||||
else
|
||||
return klass->get_framebuffer (iter);
|
||||
|
||||
iter = iter->parent;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -551,7 +551,7 @@ clutter_pipeline_node_init (ClutterPipelineNode *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_pipeline_node_new: (skip)
|
||||
* clutter_pipeline_node_new:
|
||||
* @pipeline: (allow-none): a Cogl pipeline state object, or %NULL
|
||||
*
|
||||
* Creates a new #ClutterPaintNode that will use the @pipeline to
|
||||
@ -1115,6 +1115,8 @@ struct _ClutterActorNode
|
||||
ClutterPaintNode parent_instance;
|
||||
|
||||
ClutterActor *actor;
|
||||
int opacity_override;
|
||||
int saved_opacity_override;
|
||||
};
|
||||
|
||||
struct _ClutterActorNodeClass
|
||||
@ -1130,6 +1132,14 @@ clutter_actor_node_pre_draw (ClutterPaintNode *node,
|
||||
{
|
||||
ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node);
|
||||
|
||||
if (actor_node->opacity_override != -1)
|
||||
{
|
||||
actor_node->saved_opacity_override =
|
||||
clutter_actor_get_opacity_override (actor_node->actor);
|
||||
clutter_actor_set_opacity_override (actor_node->actor,
|
||||
actor_node->opacity_override);
|
||||
}
|
||||
|
||||
CLUTTER_SET_PRIVATE_FLAGS (actor_node->actor, CLUTTER_IN_PAINT);
|
||||
|
||||
return TRUE;
|
||||
@ -1151,6 +1161,12 @@ clutter_actor_node_post_draw (ClutterPaintNode *node,
|
||||
ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node);
|
||||
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (actor_node->actor, CLUTTER_IN_PAINT);
|
||||
|
||||
if (actor_node->opacity_override != -1)
|
||||
{
|
||||
clutter_actor_set_opacity_override (actor_node->actor,
|
||||
actor_node->saved_opacity_override);
|
||||
}
|
||||
}
|
||||
|
||||
static JsonNode *
|
||||
@ -1192,6 +1208,7 @@ clutter_actor_node_init (ClutterActorNode *self)
|
||||
/*
|
||||
* clutter_actor_node_new:
|
||||
* @actor: the actor to paint
|
||||
* @opacity: opacity to draw the actor with, or -1 to use the actor's opacity
|
||||
*
|
||||
* Creates a new #ClutterActorNode.
|
||||
*
|
||||
@ -1203,7 +1220,8 @@ clutter_actor_node_init (ClutterActorNode *self)
|
||||
* Use clutter_paint_node_unref() when done.
|
||||
*/
|
||||
ClutterPaintNode *
|
||||
clutter_actor_node_new (ClutterActor *actor)
|
||||
clutter_actor_node_new (ClutterActor *actor,
|
||||
int opacity)
|
||||
{
|
||||
ClutterActorNode *res;
|
||||
|
||||
@ -1211,11 +1229,96 @@ clutter_actor_node_new (ClutterActor *actor)
|
||||
|
||||
res = _clutter_paint_node_create (CLUTTER_TYPE_ACTOR_NODE);
|
||||
res->actor = actor;
|
||||
res->opacity_override = CLAMP (opacity, -1, 255);
|
||||
|
||||
return (ClutterPaintNode *) res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ClutterEffectNode
|
||||
*/
|
||||
|
||||
struct _ClutterEffectNode
|
||||
{
|
||||
ClutterPaintNode parent_instance;
|
||||
|
||||
ClutterEffect *effect;
|
||||
};
|
||||
|
||||
struct _ClutterEffectNodeClass
|
||||
{
|
||||
ClutterPaintNodeClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterEffectNode, clutter_effect_node, CLUTTER_TYPE_PAINT_NODE)
|
||||
|
||||
static JsonNode *
|
||||
clutter_effect_node_serialize (ClutterPaintNode *node)
|
||||
{
|
||||
ClutterEffectNode *effect_node = CLUTTER_EFFECT_NODE (node);
|
||||
ClutterActorMeta *effect_meta = CLUTTER_ACTOR_META (effect_node->effect);
|
||||
g_autoptr (JsonBuilder) builder = NULL;
|
||||
g_autoptr (GString) string = NULL;
|
||||
const char *meta_name;
|
||||
|
||||
meta_name = clutter_actor_meta_get_name (effect_meta);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
g_string_append (string, G_OBJECT_TYPE_NAME (effect_node->effect));
|
||||
g_string_append (string, " (");
|
||||
if (meta_name)
|
||||
g_string_append_printf (string, "\"%s\"", meta_name);
|
||||
else
|
||||
g_string_append (string, "unnamed");
|
||||
g_string_append (string, ")");
|
||||
|
||||
builder = json_builder_new ();
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
json_builder_set_member_name (builder, "effect");
|
||||
json_builder_add_string_value (builder, string->str);
|
||||
json_builder_end_object (builder);
|
||||
|
||||
return json_builder_get_root (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_node_class_init (ClutterEffectNodeClass *klass)
|
||||
{
|
||||
ClutterPaintNodeClass *node_class;
|
||||
|
||||
node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
||||
node_class->serialize = clutter_effect_node_serialize;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_node_init (ClutterEffectNode *self)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* clutter_effect_node_new:
|
||||
* @actor: the actor to paint
|
||||
*
|
||||
* Creates a new #ClutterEffectNode.
|
||||
*
|
||||
* Return value: (transfer full): the newly created #ClutterEffectNode.
|
||||
* Use clutter_paint_node_unref() when done.
|
||||
*/
|
||||
ClutterPaintNode *
|
||||
clutter_effect_node_new (ClutterEffect *effect)
|
||||
{
|
||||
ClutterEffectNode *res;
|
||||
|
||||
g_assert (effect != NULL);
|
||||
|
||||
res = _clutter_paint_node_create (CLUTTER_TYPE_EFFECT_NODE);
|
||||
res->effect = effect;
|
||||
|
||||
return (ClutterPaintNode *) res;
|
||||
}
|
||||
|
||||
/*
|
||||
* ClutterLayerNode
|
||||
*/
|
||||
@ -1235,6 +1338,7 @@ struct _ClutterLayerNode
|
||||
CoglFramebuffer *offscreen;
|
||||
|
||||
guint8 opacity;
|
||||
gboolean update_modelview;
|
||||
};
|
||||
|
||||
struct _ClutterLayerNodeClass
|
||||
@ -1249,8 +1353,6 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterLayerNode *lnode = (ClutterLayerNode *) node;
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglMatrix matrix;
|
||||
|
||||
/* if we were unable to create an offscreen buffer for this node, then
|
||||
* we simply ignore it
|
||||
@ -1258,18 +1360,16 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node,
|
||||
if (lnode->offscreen == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* if no geometry was submitted for this node then we simply ignore it */
|
||||
if (node->operations == NULL)
|
||||
return FALSE;
|
||||
if (lnode->update_modelview)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglMatrix matrix;
|
||||
|
||||
/* copy the same modelview from the current framebuffer to the one we
|
||||
* are going to use
|
||||
*/
|
||||
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
|
||||
cogl_framebuffer_get_modelview_matrix (framebuffer, &matrix);
|
||||
|
||||
clutter_paint_context_push_framebuffer (paint_context, lnode->offscreen);
|
||||
|
||||
cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix);
|
||||
|
||||
cogl_framebuffer_set_viewport (lnode->offscreen,
|
||||
@ -1280,6 +1380,9 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node,
|
||||
|
||||
cogl_framebuffer_set_projection_matrix (lnode->offscreen,
|
||||
&lnode->projection);
|
||||
}
|
||||
|
||||
clutter_paint_context_push_framebuffer (paint_context, lnode->offscreen);
|
||||
|
||||
/* clear out the target framebuffer */
|
||||
cogl_framebuffer_clear4f (lnode->offscreen,
|
||||
@ -1307,6 +1410,10 @@ clutter_layer_node_post_draw (ClutterPaintNode *node,
|
||||
cogl_framebuffer_pop_matrix (lnode->offscreen);
|
||||
clutter_paint_context_pop_framebuffer (paint_context);
|
||||
|
||||
/* if no geometry was submitted for this node then we simply ignore it */
|
||||
if (node->operations == NULL)
|
||||
return;
|
||||
|
||||
fb = clutter_paint_context_get_framebuffer (paint_context);
|
||||
|
||||
for (i = 0; i < node->operations->len; i++)
|
||||
@ -1367,6 +1474,25 @@ clutter_layer_node_finalize (ClutterPaintNode *node)
|
||||
CLUTTER_PAINT_NODE_CLASS (clutter_layer_node_parent_class)->finalize (node);
|
||||
}
|
||||
|
||||
static JsonNode *
|
||||
clutter_layer_node_serialize (ClutterPaintNode *node)
|
||||
{
|
||||
ClutterLayerNode *layer_node = CLUTTER_LAYER_NODE (node);
|
||||
g_autoptr (JsonBuilder) builder = NULL;
|
||||
g_autofree char *framebuffer_ptr = NULL;
|
||||
|
||||
builder = json_builder_new ();
|
||||
|
||||
framebuffer_ptr = g_strdup_printf ("%p", layer_node->offscreen);
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
json_builder_set_member_name (builder, "framebuffer");
|
||||
json_builder_add_string_value (builder, framebuffer_ptr);
|
||||
json_builder_end_object (builder);
|
||||
|
||||
return json_builder_get_root (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_layer_node_class_init (ClutterLayerNodeClass *klass)
|
||||
{
|
||||
@ -1376,6 +1502,7 @@ clutter_layer_node_class_init (ClutterLayerNodeClass *klass)
|
||||
node_class->pre_draw = clutter_layer_node_pre_draw;
|
||||
node_class->post_draw = clutter_layer_node_post_draw;
|
||||
node_class->finalize = clutter_layer_node_finalize;
|
||||
node_class->serialize = clutter_layer_node_serialize;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1418,6 +1545,7 @@ clutter_layer_node_new (const CoglMatrix *projection,
|
||||
|
||||
res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
|
||||
|
||||
res->update_modelview = TRUE;
|
||||
res->projection = *projection;
|
||||
res->viewport = *viewport;
|
||||
res->fbo_width = width;
|
||||
@ -1458,3 +1586,233 @@ out:
|
||||
|
||||
return (ClutterPaintNode *) res;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_layer_node_new_with_framebuffer:
|
||||
* @framebuffer: a #CoglFramebuffer
|
||||
* @pipeline: a #CoglPipeline
|
||||
* @opacity: the opacity to be used when drawing the layer
|
||||
*
|
||||
* Creates a new #ClutterLayerNode with @framebuffer and
|
||||
* @pipeline. @framebuffer will then be painted using the
|
||||
* given @opacity.
|
||||
*
|
||||
* When using this constructor, the caller is responsible
|
||||
* for setting up the framebuffer's modelview and projection
|
||||
* matrices.
|
||||
*
|
||||
* Return value: (transfer full)(nullable): the newly created #ClutterLayerNode.
|
||||
* Use clutter_paint_node_unref() when done.
|
||||
*/
|
||||
ClutterPaintNode *
|
||||
clutter_layer_node_new_with_framebuffer (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
guint8 opacity)
|
||||
{
|
||||
ClutterLayerNode *res;
|
||||
CoglColor color;
|
||||
|
||||
g_return_val_if_fail (cogl_is_framebuffer (framebuffer), NULL);
|
||||
|
||||
res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
|
||||
|
||||
res->update_modelview = FALSE;
|
||||
res->offscreen = cogl_object_ref (framebuffer);
|
||||
res->pipeline = cogl_pipeline_copy (pipeline);
|
||||
|
||||
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
|
||||
cogl_pipeline_set_color (res->pipeline, &color);
|
||||
|
||||
return (ClutterPaintNode *) res;
|
||||
}
|
||||
|
||||
/*
|
||||
* ClutterBlitNode
|
||||
*/
|
||||
|
||||
struct _ClutterBlitNode
|
||||
{
|
||||
ClutterPaintNode parent_instance;
|
||||
|
||||
CoglFramebuffer *src;
|
||||
CoglFramebuffer *dst;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterBlitNode, clutter_blit_node, CLUTTER_TYPE_PAINT_NODE)
|
||||
|
||||
static gboolean
|
||||
clutter_blit_node_pre_draw (ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blit_node_draw (ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterBlitNode *blit_node = CLUTTER_BLIT_NODE (node);
|
||||
g_autoptr (GError) error = NULL;
|
||||
guint i;
|
||||
|
||||
if (node->operations == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < node->operations->len; i++)
|
||||
{
|
||||
const ClutterPaintOperation *op;
|
||||
float op_width, op_height;
|
||||
|
||||
op = &g_array_index (node->operations, ClutterPaintOperation, i);
|
||||
|
||||
switch (op->opcode)
|
||||
{
|
||||
case PAINT_OP_INVALID:
|
||||
break;
|
||||
|
||||
case PAINT_OP_TEX_RECT:
|
||||
op_width = op->op.texrect[6] - op->op.texrect[4];
|
||||
op_height = op->op.texrect[7] - op->op.texrect[5];
|
||||
|
||||
cogl_blit_framebuffer (blit_node->src,
|
||||
blit_node->dst,
|
||||
op->op.texrect[0],
|
||||
op->op.texrect[1],
|
||||
op->op.texrect[4],
|
||||
op->op.texrect[5],
|
||||
op_width,
|
||||
op_height,
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Error blitting framebuffers: %s", error->message);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAINT_OP_MULTITEX_RECT:
|
||||
case PAINT_OP_PRIMITIVE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blit_node_finalize (ClutterPaintNode *node)
|
||||
{
|
||||
ClutterBlitNode *blit_node = CLUTTER_BLIT_NODE (node);
|
||||
|
||||
cogl_clear_object (&blit_node->src);
|
||||
cogl_clear_object (&blit_node->dst);
|
||||
|
||||
CLUTTER_PAINT_NODE_CLASS (clutter_blit_node_parent_class)->finalize (node);
|
||||
}
|
||||
|
||||
static JsonNode *
|
||||
clutter_blit_node_serialize (ClutterPaintNode *node)
|
||||
{
|
||||
ClutterBlitNode *blit_node = CLUTTER_BLIT_NODE (node);
|
||||
g_autoptr (JsonBuilder) builder = NULL;
|
||||
g_autofree char *src_ptr = NULL;
|
||||
g_autofree char *dst_ptr = NULL;
|
||||
|
||||
builder = json_builder_new ();
|
||||
|
||||
src_ptr = g_strdup_printf ("%p", blit_node->src);
|
||||
dst_ptr = g_strdup_printf ("%p", blit_node->dst);
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
json_builder_set_member_name (builder, "source");
|
||||
json_builder_add_string_value (builder, src_ptr);
|
||||
json_builder_end_object (builder);
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
json_builder_set_member_name (builder, "dst");
|
||||
json_builder_add_string_value (builder, dst_ptr);
|
||||
json_builder_end_object (builder);
|
||||
|
||||
return json_builder_get_root (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blit_node_class_init (ClutterTransformNodeClass *klass)
|
||||
{
|
||||
ClutterPaintNodeClass *node_class;
|
||||
|
||||
node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
||||
node_class->pre_draw = clutter_blit_node_pre_draw;
|
||||
node_class->draw = clutter_blit_node_draw;
|
||||
node_class->finalize = clutter_blit_node_finalize;
|
||||
node_class->serialize = clutter_blit_node_serialize;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blit_node_init (ClutterBlitNode *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blit_node_new:
|
||||
* @src: the source #CoglFramebuffer
|
||||
* @dst: the destination #CoglFramebuffer
|
||||
*
|
||||
* Creates a new #ClutterBlitNode that blits @src into @dst.
|
||||
*
|
||||
* You must only add rectangles using clutter_blit_node_add_blit_rectangle().
|
||||
*
|
||||
* Return value: (transfer full): the newly created #ClutterBlitNode.
|
||||
* Use clutter_paint_node_unref() when done.
|
||||
*/
|
||||
ClutterPaintNode *
|
||||
clutter_blit_node_new (CoglFramebuffer *src,
|
||||
CoglFramebuffer *dst)
|
||||
{
|
||||
ClutterBlitNode *res;
|
||||
|
||||
g_return_val_if_fail (cogl_is_framebuffer (src), NULL);
|
||||
g_return_val_if_fail (cogl_is_framebuffer (dst), NULL);
|
||||
|
||||
res = _clutter_paint_node_create (CLUTTER_TYPE_BLIT_NODE);
|
||||
res->src = cogl_object_ref (src);
|
||||
res->dst = cogl_object_ref (dst);
|
||||
|
||||
return (ClutterPaintNode *) res;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blit_node_add_blit_rectangle:
|
||||
* @blit_node: a #ClutterBlitNode
|
||||
* @src_x: Source x position
|
||||
* @src_y: Source y position
|
||||
* @dst_x: Destination x position
|
||||
* @dst_y: Destination y position
|
||||
* @width: Width of region to copy
|
||||
* @height: Height of region to copy
|
||||
*
|
||||
* Adds a new blit rectangle to the stack of rectangles. All the
|
||||
* constraints of cogl_blit_framebuffer() apply here.
|
||||
*/
|
||||
void
|
||||
clutter_blit_node_add_blit_rectangle (ClutterBlitNode *blit_node,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_BLIT_NODE (blit_node));
|
||||
|
||||
clutter_paint_node_add_texture_rectangle (CLUTTER_PAINT_NODE (blit_node),
|
||||
&(ClutterActorBox) {
|
||||
.x1 = src_x,
|
||||
.y1 = src_y,
|
||||
.x2 = src_x + width,
|
||||
.y2 = src_y + height,
|
||||
},
|
||||
dst_x,
|
||||
dst_y,
|
||||
dst_x + width,
|
||||
dst_y + height);
|
||||
}
|
||||
|
@ -160,7 +160,8 @@ CLUTTER_EXPORT
|
||||
GType clutter_actor_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_actor_node_new (ClutterActor *actor);
|
||||
ClutterPaintNode * clutter_actor_node_new (ClutterActor *actor,
|
||||
int opacity);
|
||||
|
||||
#define CLUTTER_TYPE_ROOT_NODE (clutter_root_node_get_type ())
|
||||
#define CLUTTER_ROOT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ROOT_NODE, ClutterRootNode))
|
||||
@ -208,6 +209,11 @@ ClutterPaintNode * clutter_layer_node_new (const CoglMatrix
|
||||
float height,
|
||||
guint8 opacity);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_layer_node_new_with_framebuffer (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
guint8 opacity);
|
||||
|
||||
|
||||
#define CLUTTER_TYPE_TRANSFORM_NODE (clutter_transform_node_get_type ())
|
||||
#define CLUTTER_TRANSFORM_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TRANSFORM_NODE, ClutterTransformNode))
|
||||
@ -230,6 +236,36 @@ GType clutter_transform_node_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_transform_node_new (const CoglMatrix *projection);
|
||||
|
||||
#define CLUTTER_TYPE_BLIT_NODE (clutter_blit_node_get_type ())
|
||||
#define CLUTTER_BLIT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BLIT_NODE, ClutterBlitNode))
|
||||
#define CLUTTER_IS_BLIT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BLIT_NODE))
|
||||
|
||||
/*
|
||||
* ClutterBlitNode:
|
||||
*
|
||||
* The #ClutterLayerNode structure is an opaque
|
||||
* type whose members cannot be directly accessed.
|
||||
*/
|
||||
typedef struct _ClutterBlitNode ClutterBlitNode;
|
||||
typedef struct _ClutterPaintNodeClass ClutterBlitNodeClass;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_blit_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_blit_node_new (CoglFramebuffer *src,
|
||||
CoglFramebuffer *dst);
|
||||
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_blit_node_add_blit_rectangle (ClutterBlitNode *blit_node,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_PAINT_NODES_H__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user