paint-node: Get the framebuffer from the root node

The PaintNode hierarchy should have the ability to retrieve the
current active framebuffer by itself, instead of asking Cogl using the
global state API.

In order to do this, we ask the root node of a PaintNode graph for the
active framebuffer. In the current, 1.x-compatibility mode we have two
potential root node types: ClutterRootNode, used by ClutterStage; and
ClutterDummyNode, used a local root for each actor. The former takes a
framebuffer as part of its construction; the latter takes the actor that
acts as the local top-level during the actor's paint sequence, which
means we can get the active framebuffer from the stage associated to the
actor.

By keeping track of the active framebuffer on the node themselves we can
drop the usage of cogl_get_draw_framebuffer() in their implementation.
This commit is contained in:
Emmanuele Bassi 2013-12-03 12:50:39 +00:00
parent e619de20d8
commit a64742f3e4
3 changed files with 64 additions and 10 deletions

View File

@ -68,6 +68,8 @@ struct _ClutterPaintNodeClass
void (* post_draw) (ClutterPaintNode *node); void (* post_draw) (ClutterPaintNode *node);
JsonNode*(* serialize) (ClutterPaintNode *node); JsonNode*(* serialize) (ClutterPaintNode *node);
CoglFramebuffer *(* get_framebuffer) (ClutterPaintNode *node);
}; };
#define PAINT_OP_INIT { PAINT_OP_INVALID } #define PAINT_OP_INIT { PAINT_OP_INVALID }
@ -137,6 +139,8 @@ G_GNUC_INTERNAL
ClutterPaintNode * clutter_paint_node_get_last_child (ClutterPaintNode *node); ClutterPaintNode * clutter_paint_node_get_last_child (ClutterPaintNode *node);
G_GNUC_INTERNAL G_GNUC_INTERNAL
ClutterPaintNode * clutter_paint_node_get_parent (ClutterPaintNode *node); ClutterPaintNode * clutter_paint_node_get_parent (ClutterPaintNode *node);
G_GNUC_INTERNAL
CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node);
#define CLUTTER_TYPE_LAYER_NODE (_clutter_layer_node_get_type ()) #define CLUTTER_TYPE_LAYER_NODE (_clutter_layer_node_get_type ())
#define CLUTTER_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYER_NODE, ClutterLayerNode)) #define CLUTTER_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYER_NODE, ClutterLayerNode))

View File

@ -1123,3 +1123,31 @@ _clutter_paint_node_create (GType gtype)
return (gpointer) g_type_create_instance (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;
}
CoglFramebuffer *
clutter_paint_node_get_framebuffer (ClutterPaintNode *node)
{
ClutterPaintNode *root = clutter_paint_node_get_root (node);
ClutterPaintNodeClass *klass;
if (root == NULL)
return NULL;
klass = CLUTTER_PAINT_NODE_GET_CLASS (root);
if (klass->get_framebuffer != NULL)
return klass->get_framebuffer (root);
return cogl_get_draw_framebuffer ();
}

View File

@ -135,6 +135,14 @@ clutter_root_node_finalize (ClutterPaintNode *node)
CLUTTER_PAINT_NODE_CLASS (clutter_root_node_parent_class)->finalize (node); CLUTTER_PAINT_NODE_CLASS (clutter_root_node_parent_class)->finalize (node);
} }
static CoglFramebuffer *
clutter_root_node_get_framebuffer (ClutterPaintNode *node)
{
ClutterRootNode *rnode = (ClutterRootNode *) node;
return rnode->framebuffer;
}
static void static void
clutter_root_node_class_init (ClutterRootNodeClass *klass) clutter_root_node_class_init (ClutterRootNodeClass *klass)
{ {
@ -143,6 +151,7 @@ clutter_root_node_class_init (ClutterRootNodeClass *klass)
node_class->pre_draw = clutter_root_node_pre_draw; node_class->pre_draw = clutter_root_node_pre_draw;
node_class->post_draw = clutter_root_node_post_draw; node_class->post_draw = clutter_root_node_post_draw;
node_class->finalize = clutter_root_node_finalize; node_class->finalize = clutter_root_node_finalize;
node_class->get_framebuffer = clutter_root_node_get_framebuffer;
} }
static void static void
@ -262,6 +271,7 @@ struct _ClutterDummyNode
ClutterPaintNode parent_instance; ClutterPaintNode parent_instance;
ClutterActor *actor; ClutterActor *actor;
CoglFramebuffer *framebuffer;
}; };
G_DEFINE_TYPE (ClutterDummyNode, clutter_dummy_node, CLUTTER_TYPE_PAINT_NODE) G_DEFINE_TYPE (ClutterDummyNode, clutter_dummy_node, CLUTTER_TYPE_PAINT_NODE)
@ -296,6 +306,14 @@ clutter_dummy_node_serialize (ClutterPaintNode *node)
return res; return res;
} }
static CoglFramebuffer *
clutter_dummy_node_get_framebuffer (ClutterPaintNode *node)
{
ClutterDummyNode *dnode = (ClutterDummyNode *) node;
return dnode->framebuffer;
}
static void static void
clutter_dummy_node_class_init (ClutterDummyNodeClass *klass) clutter_dummy_node_class_init (ClutterDummyNodeClass *klass)
{ {
@ -303,6 +321,7 @@ clutter_dummy_node_class_init (ClutterDummyNodeClass *klass)
node_class->pre_draw = clutter_dummy_node_pre_draw; node_class->pre_draw = clutter_dummy_node_pre_draw;
node_class->serialize = clutter_dummy_node_serialize; node_class->serialize = clutter_dummy_node_serialize;
node_class->get_framebuffer = clutter_dummy_node_get_framebuffer;
} }
static void static void
@ -314,10 +333,13 @@ ClutterPaintNode *
_clutter_dummy_node_new (ClutterActor *actor) _clutter_dummy_node_new (ClutterActor *actor)
{ {
ClutterPaintNode *res; ClutterPaintNode *res;
ClutterDummyNode *dnode;
res = _clutter_paint_node_create (_clutter_dummy_node_get_type ()); res = _clutter_paint_node_create (_clutter_dummy_node_get_type ());
((ClutterDummyNode *) res)->actor = actor; dnode = (ClutterDummyNode *) res;
dnode->actor = actor;
dnode->framebuffer = _clutter_actor_get_active_framebuffer (actor);
return res; return res;
} }
@ -378,6 +400,7 @@ static void
clutter_pipeline_node_draw (ClutterPaintNode *node) clutter_pipeline_node_draw (ClutterPaintNode *node)
{ {
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node); ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
CoglFramebuffer *fb;
guint i; guint i;
if (pnode->pipeline == NULL) if (pnode->pipeline == NULL)
@ -386,6 +409,8 @@ clutter_pipeline_node_draw (ClutterPaintNode *node)
if (node->operations == NULL) if (node->operations == NULL)
return; return;
fb = clutter_paint_node_get_framebuffer (node);
for (i = 0; i < node->operations->len; i++) for (i = 0; i < node->operations->len; i++)
{ {
const ClutterPaintOperation *op; const ClutterPaintOperation *op;
@ -413,12 +438,9 @@ clutter_pipeline_node_draw (ClutterPaintNode *node)
break; break;
case PAINT_OP_PRIMITIVE: case PAINT_OP_PRIMITIVE:
{ cogl_framebuffer_draw_primitive (fb,
CoglFramebuffer *fb = cogl_get_draw_framebuffer (); pnode->pipeline,
cogl_framebuffer_draw_primitive (fb, pnode->pipeline,
op->op.primitive); op->op.primitive);
}
break; break;
} }
} }
@ -764,7 +786,7 @@ clutter_text_node_draw (ClutterPaintNode *node)
if (node->operations == NULL) if (node->operations == NULL)
return; return;
fb = cogl_get_draw_framebuffer (); fb = clutter_paint_node_get_framebuffer (node);
pango_layout_get_pixel_extents (tnode->layout, NULL, &extents); pango_layout_get_pixel_extents (tnode->layout, NULL, &extents);
@ -948,7 +970,7 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node)
if (node->operations == NULL) if (node->operations == NULL)
return FALSE; return FALSE;
fb = cogl_get_draw_framebuffer (); fb = clutter_paint_node_get_framebuffer (node);
for (i = 0; i < node->operations->len; i++) for (i = 0; i < node->operations->len; i++)
{ {
@ -990,7 +1012,7 @@ clutter_clip_node_post_draw (ClutterPaintNode *node)
if (node->operations == NULL) if (node->operations == NULL)
return; return;
fb = cogl_get_draw_framebuffer (); fb = clutter_paint_node_get_framebuffer (node);
for (i = 0; i < node->operations->len; i++) for (i = 0; i < node->operations->len; i++)
{ {