paint-node: Use JSON-GLib for debug serialization
Instead of our homegrown string building; this at least ensures that we're generating proper data, instead of random strings. Plus, using JsonNode and JsonBuilder, we can ask the PaintNode subclasses to serialize themselves in a sensible way.
This commit is contained in:
parent
2ee5851970
commit
f4d8fb054a
@ -26,6 +26,7 @@
|
|||||||
#define __CLUTTER_PAINT_NODE_PRIVATE_H__
|
#define __CLUTTER_PAINT_NODE_PRIVATE_H__
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <json-glib/json-glib.h>
|
||||||
#include <clutter/clutter-paint-node.h>
|
#include <clutter/clutter-paint-node.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
@ -65,6 +66,8 @@ struct _ClutterPaintNodeClass
|
|||||||
gboolean (* pre_draw) (ClutterPaintNode *node);
|
gboolean (* pre_draw) (ClutterPaintNode *node);
|
||||||
void (* draw) (ClutterPaintNode *node);
|
void (* draw) (ClutterPaintNode *node);
|
||||||
void (* post_draw) (ClutterPaintNode *node);
|
void (* post_draw) (ClutterPaintNode *node);
|
||||||
|
|
||||||
|
JsonNode*(* serialize) (ClutterPaintNode *node);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
|
|
||||||
#include <pango/pango.h>
|
#include <pango/pango.h>
|
||||||
#include <cogl/cogl.h>
|
#include <cogl/cogl.h>
|
||||||
|
#include <json-glib/json-glib.h>
|
||||||
|
|
||||||
#include "clutter-paint-node-private.h"
|
#include "clutter-paint-node-private.h"
|
||||||
|
|
||||||
@ -778,47 +779,6 @@ clutter_paint_operation_clear (ClutterPaintOperation *op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
clutter_paint_operation_to_string (const ClutterPaintOperation *op,
|
|
||||||
GString *buf,
|
|
||||||
int level)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < level; i++)
|
|
||||||
g_string_append (buf, " ");
|
|
||||||
|
|
||||||
g_string_append (buf, "{ ");
|
|
||||||
|
|
||||||
switch (op->opcode)
|
|
||||||
{
|
|
||||||
case PAINT_OP_INVALID:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PAINT_OP_TEX_RECT:
|
|
||||||
g_string_append_printf (buf, "\"texrect\" : [ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ]",
|
|
||||||
op->op.texrect[0],
|
|
||||||
op->op.texrect[1],
|
|
||||||
op->op.texrect[2],
|
|
||||||
op->op.texrect[3],
|
|
||||||
op->op.texrect[4],
|
|
||||||
op->op.texrect[5],
|
|
||||||
op->op.texrect[6],
|
|
||||||
op->op.texrect[7]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PAINT_OP_PATH:
|
|
||||||
g_string_append_printf (buf, "\"path\" : \"0x%p\"", op->op.path);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PAINT_OP_PRIMITIVE:
|
|
||||||
g_string_append_printf (buf, "\"primitive\" : \"0x%p\"", op->op.primitive);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_string_append (buf, " }");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
clutter_paint_op_init_tex_rect (ClutterPaintOperation *op,
|
clutter_paint_op_init_tex_rect (ClutterPaintOperation *op,
|
||||||
const ClutterActorBox *rect,
|
const ClutterActorBox *rect,
|
||||||
@ -1016,113 +976,130 @@ _clutter_paint_node_paint (ClutterPaintNode *node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
#ifdef CLUTTER_ENABLE_DEBUG
|
||||||
clutter_paint_node_to_string (ClutterPaintNode *node,
|
static JsonNode *
|
||||||
GString *buf,
|
clutter_paint_node_serialize (ClutterPaintNode *node)
|
||||||
int level)
|
|
||||||
{
|
{
|
||||||
ClutterPaintNode *iter;
|
ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node);
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < level; i++)
|
if (klass->serialize != NULL)
|
||||||
g_string_append (buf, " ");
|
return klass->serialize (node);
|
||||||
|
|
||||||
g_string_append_c (buf, '"');
|
return json_node_new (JSON_NODE_NULL);
|
||||||
g_string_append (buf, g_type_name (G_TYPE_FROM_INSTANCE (node)));
|
}
|
||||||
g_string_append_c (buf, '"');
|
|
||||||
|
|
||||||
g_string_append (buf, " : {\n");
|
static JsonNode *
|
||||||
|
clutter_paint_node_to_json (ClutterPaintNode *node)
|
||||||
|
{
|
||||||
|
JsonBuilder *builder;
|
||||||
|
JsonNode *res;
|
||||||
|
|
||||||
if (node->name != NULL)
|
builder = json_builder_new ();
|
||||||
{
|
|
||||||
for (i = 0; i < level + 1; i++)
|
|
||||||
g_string_append (buf, " ");
|
|
||||||
|
|
||||||
g_string_append_printf (buf, "\"name\" : \"%s\"", node->name);
|
json_builder_begin_object (builder);
|
||||||
|
|
||||||
if (node->operations != NULL ||
|
json_builder_set_member_name (builder, "type");
|
||||||
node->first_child != NULL)
|
json_builder_add_string_value (builder, g_type_name (G_TYPE_FROM_INSTANCE (node)));
|
||||||
g_string_append_c (buf, ',');
|
|
||||||
|
|
||||||
g_string_append_c (buf, '\n');
|
json_builder_set_member_name (builder, "name");
|
||||||
}
|
json_builder_add_string_value (builder, node->name);
|
||||||
|
|
||||||
|
json_builder_set_member_name (builder, "node-data");
|
||||||
|
json_builder_add_value (builder, clutter_paint_node_serialize (node));
|
||||||
|
|
||||||
|
json_builder_set_member_name (builder, "operations");
|
||||||
|
json_builder_begin_array (builder);
|
||||||
|
|
||||||
if (node->operations != NULL)
|
if (node->operations != NULL)
|
||||||
{
|
{
|
||||||
guint o;
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < level + 1; i++)
|
for (i = 0; i < node->operations->len; i++)
|
||||||
g_string_append (buf, " ");
|
|
||||||
|
|
||||||
g_string_append (buf, "\"operations\" : [\n");
|
|
||||||
|
|
||||||
for (o = 0; o < node->operations->len; o++)
|
|
||||||
{
|
{
|
||||||
const ClutterPaintOperation *op;
|
const ClutterPaintOperation *op;
|
||||||
|
|
||||||
op = &g_array_index (node->operations, ClutterPaintOperation, o);
|
op = &g_array_index (node->operations, ClutterPaintOperation, i);
|
||||||
clutter_paint_operation_to_string (op, buf, level + 2);
|
json_builder_begin_object (builder);
|
||||||
|
|
||||||
if ((o + 1) != node->operations->len)
|
switch (op->opcode)
|
||||||
g_string_append_c (buf, ',');
|
{
|
||||||
|
case PAINT_OP_TEX_RECT:
|
||||||
|
json_builder_set_member_name (builder, "texrect");
|
||||||
|
json_builder_begin_array (builder);
|
||||||
|
json_builder_add_double_value (builder, op->op.texrect[0]);
|
||||||
|
json_builder_add_double_value (builder, op->op.texrect[1]);
|
||||||
|
json_builder_add_double_value (builder, op->op.texrect[2]);
|
||||||
|
json_builder_add_double_value (builder, op->op.texrect[3]);
|
||||||
|
json_builder_add_double_value (builder, op->op.texrect[4]);
|
||||||
|
json_builder_add_double_value (builder, op->op.texrect[5]);
|
||||||
|
json_builder_add_double_value (builder, op->op.texrect[6]);
|
||||||
|
json_builder_add_double_value (builder, op->op.texrect[7]);
|
||||||
|
json_builder_end_array (builder);
|
||||||
|
break;
|
||||||
|
|
||||||
g_string_append_c (buf, '\n');
|
case PAINT_OP_PATH:
|
||||||
|
json_builder_set_member_name (builder, "path");
|
||||||
|
json_builder_add_int_value (builder, (gint64) op->op.path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAINT_OP_PRIMITIVE:
|
||||||
|
json_builder_set_member_name (builder, "primitive");
|
||||||
|
json_builder_add_int_value (builder, (gint64) op->op.primitive);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAINT_OP_INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_builder_end_object (builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < level + 1; i++)
|
|
||||||
g_string_append (buf, " ");
|
|
||||||
|
|
||||||
g_string_append (buf, "]");
|
|
||||||
|
|
||||||
if (node->first_child != NULL)
|
|
||||||
g_string_append_c (buf, ',');
|
|
||||||
|
|
||||||
g_string_append_c (buf, '\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->first_child == NULL)
|
json_builder_end_array (builder);
|
||||||
goto out;
|
|
||||||
|
|
||||||
for (i = 0; i < level + 1; i++)
|
json_builder_set_member_name (builder, "children");
|
||||||
g_string_append (buf, " ");
|
json_builder_begin_array (builder);
|
||||||
|
|
||||||
g_string_append (buf, "\"children\" : [\n");
|
if (node->first_child != NULL)
|
||||||
|
|
||||||
for (iter = node->first_child;
|
|
||||||
iter != NULL;
|
|
||||||
iter = iter->next_sibling)
|
|
||||||
{
|
{
|
||||||
clutter_paint_node_to_string (iter, buf, level + 2);
|
ClutterPaintNode *child;
|
||||||
|
|
||||||
if (iter->next_sibling != NULL)
|
for (child = node->first_child;
|
||||||
g_string_append (buf, ",\n");
|
child != NULL;
|
||||||
else
|
child = child->next_sibling)
|
||||||
g_string_append (buf, "\n");
|
{
|
||||||
|
JsonNode *n = clutter_paint_node_to_json (child);
|
||||||
|
|
||||||
|
json_builder_add_value (builder, n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < level + 1; i++)
|
json_builder_end_array (builder);
|
||||||
g_string_append (buf, " ");
|
|
||||||
|
|
||||||
g_string_append (buf, "]\n");
|
json_builder_end_object (builder);
|
||||||
|
|
||||||
out:
|
res = json_builder_get_root (builder);
|
||||||
for (i = 0; i < level; i++)
|
|
||||||
g_string_append (buf, " ");
|
|
||||||
|
|
||||||
g_string_append (buf, "}");
|
g_object_unref (builder);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_paint_node_dump_tree (ClutterPaintNode *node)
|
_clutter_paint_node_dump_tree (ClutterPaintNode *node)
|
||||||
{
|
{
|
||||||
#ifdef CLUTTER_ENABLE_DEBUG
|
#ifdef CLUTTER_ENABLE_DEBUG
|
||||||
GString *buf = g_string_sized_new (1024);
|
JsonGenerator *gen = json_generator_new ();
|
||||||
|
char *str;
|
||||||
|
gsize len;
|
||||||
|
|
||||||
clutter_paint_node_to_string (node, buf, 0);
|
json_generator_set_root (gen, clutter_paint_node_to_json (node));
|
||||||
|
str = json_generator_to_data (gen, &len);
|
||||||
|
|
||||||
CLUTTER_NOTE (PAINT, "Render tree:\n%s", buf->str);
|
g_print ("Render tree starting from %p:\n%s\n", node, str);
|
||||||
|
|
||||||
g_string_free (buf, TRUE);
|
g_free (str);
|
||||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,6 +398,46 @@ clutter_pipeline_node_post_draw (ClutterPaintNode *node)
|
|||||||
cogl_pop_source ();
|
cogl_pop_source ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JsonNode *
|
||||||
|
clutter_pipeline_node_serialize (ClutterPaintNode *node)
|
||||||
|
{
|
||||||
|
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
|
||||||
|
JsonBuilder *builder;
|
||||||
|
CoglColor color;
|
||||||
|
JsonNode *res;
|
||||||
|
|
||||||
|
if (pnode->pipeline == NULL)
|
||||||
|
return json_node_new (JSON_NODE_NULL);
|
||||||
|
|
||||||
|
builder = json_builder_new ();
|
||||||
|
json_builder_begin_object (builder);
|
||||||
|
|
||||||
|
cogl_pipeline_get_color (pnode->pipeline, &color);
|
||||||
|
json_builder_set_member_name (builder, "color");
|
||||||
|
json_builder_begin_array (builder);
|
||||||
|
json_builder_add_double_value (builder, cogl_color_get_red (&color));
|
||||||
|
json_builder_add_double_value (builder, cogl_color_get_green (&color));
|
||||||
|
json_builder_add_double_value (builder, cogl_color_get_blue (&color));
|
||||||
|
json_builder_add_double_value (builder, cogl_color_get_alpha (&color));
|
||||||
|
json_builder_end_array (builder);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
json_builder_set_member_name (builder, "layers");
|
||||||
|
json_builder_begin_array (builder);
|
||||||
|
cogl_pipeline_foreach_layer (pnode->pipeline,
|
||||||
|
clutter_pipeline_node_serialize_layer,
|
||||||
|
builder);
|
||||||
|
json_builder_end_array (builder);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
json_builder_end_object (builder);
|
||||||
|
|
||||||
|
res = json_builder_get_root (builder);
|
||||||
|
g_object_unref (builder);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_pipeline_node_class_init (ClutterPipelineNodeClass *klass)
|
clutter_pipeline_node_class_init (ClutterPipelineNodeClass *klass)
|
||||||
{
|
{
|
||||||
@ -408,6 +448,7 @@ clutter_pipeline_node_class_init (ClutterPipelineNodeClass *klass)
|
|||||||
node_class->draw = clutter_pipeline_node_draw;
|
node_class->draw = clutter_pipeline_node_draw;
|
||||||
node_class->post_draw = clutter_pipeline_node_post_draw;
|
node_class->post_draw = clutter_pipeline_node_post_draw;
|
||||||
node_class->finalize = clutter_pipeline_node_finalize;
|
node_class->finalize = clutter_pipeline_node_finalize;
|
||||||
|
node_class->serialize = clutter_pipeline_node_serialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -714,6 +755,47 @@ clutter_text_node_draw (ClutterPaintNode *node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JsonNode *
|
||||||
|
clutter_text_node_serialize (ClutterPaintNode *node)
|
||||||
|
{
|
||||||
|
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
|
||||||
|
JsonBuilder *builder;
|
||||||
|
JsonNode *res;
|
||||||
|
|
||||||
|
builder = json_builder_new ();
|
||||||
|
|
||||||
|
json_builder_begin_object (builder);
|
||||||
|
|
||||||
|
json_builder_set_member_name (builder, "layout");
|
||||||
|
|
||||||
|
if (pango_layout_get_character_count (tnode->layout) > 12)
|
||||||
|
{
|
||||||
|
const char *text = pango_layout_get_text (tnode->layout);
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = g_strndup (text, 12);
|
||||||
|
json_builder_add_string_value (builder, str);
|
||||||
|
g_free (str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
json_builder_add_string_value (builder, pango_layout_get_text (tnode->layout));
|
||||||
|
|
||||||
|
json_builder_set_member_name (builder, "color");
|
||||||
|
json_builder_begin_array (builder);
|
||||||
|
json_builder_add_double_value (builder, cogl_color_get_red (&tnode->color));
|
||||||
|
json_builder_add_double_value (builder, cogl_color_get_green (&tnode->color));
|
||||||
|
json_builder_add_double_value (builder, cogl_color_get_blue (&tnode->color));
|
||||||
|
json_builder_add_double_value (builder, cogl_color_get_alpha (&tnode->color));
|
||||||
|
json_builder_end_array (builder);
|
||||||
|
|
||||||
|
json_builder_end_object (builder);
|
||||||
|
|
||||||
|
res = json_builder_get_root (builder);
|
||||||
|
g_object_unref (builder);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_text_node_class_init (ClutterTextNodeClass *klass)
|
clutter_text_node_class_init (ClutterTextNodeClass *klass)
|
||||||
{
|
{
|
||||||
@ -722,6 +804,7 @@ clutter_text_node_class_init (ClutterTextNodeClass *klass)
|
|||||||
node_class->pre_draw = clutter_text_node_pre_draw;
|
node_class->pre_draw = clutter_text_node_pre_draw;
|
||||||
node_class->draw = clutter_text_node_draw;
|
node_class->draw = clutter_text_node_draw;
|
||||||
node_class->finalize = clutter_text_node_finalize;
|
node_class->finalize = clutter_text_node_finalize;
|
||||||
|
node_class->serialize = clutter_text_node_serialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user