forked from AuroraMiddleware/gtk
Turn GskRenderNode into a derivable type
Language bindings—especially ones based on introspection—cannot deal with custom type hiearchies. Luckily for us, GType has a derivable type with low overhead: GTypeInstance. By turning GskRenderNode into a GTypeInstance, and creating derived types for each class of node, we can provide an introspectable API to our non-C API consumers, with no functional change to the C API itself.
This commit is contained in:
parent
5e095cd208
commit
d701a89281
@ -595,7 +595,7 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
|
||||
n = gsk_linear_gradient_node_get_n_color_stops (node);
|
||||
add_uint32 (nodes, n);
|
||||
for (i = 0; i < n; i++)
|
||||
add_color_stop (nodes, &gsk_linear_gradient_node_peek_color_stops (node)[i]);
|
||||
add_color_stop (nodes, &gsk_linear_gradient_node_peek_color_stops (node, NULL)[i]);
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -25,7 +25,7 @@ node_sample_add (NodeSample *self,
|
||||
g_assert (node_type <= N_NODE_TYPES);
|
||||
|
||||
if (self->nodes[node_type].class_name == NULL)
|
||||
self->nodes[node_type].class_name = node->node_class->type_name;
|
||||
self->nodes[node_type].class_name = g_type_name_from_instance ((GTypeInstance *) node);
|
||||
|
||||
self->nodes[node_type].count ++;
|
||||
self->count ++;
|
||||
|
@ -150,7 +150,7 @@ print_render_node_tree (GskRenderNode *root, int level)
|
||||
break;
|
||||
|
||||
default:
|
||||
g_print ("%*s %s\n", level * INDENT, " ", root->node_class->type_name);
|
||||
g_print ("%*s %s\n", level * INDENT, " ", g_type_name_from_instance ((GTypeInstance *) root));
|
||||
}
|
||||
|
||||
#undef INDENT
|
||||
@ -623,7 +623,9 @@ render_fallback_node (GskGLRenderer *self,
|
||||
surface,
|
||||
GL_NEAREST, GL_NEAREST);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||
"Fallback %s %d", node->node_class->type_name, texture_id);
|
||||
"Fallback %s %d",
|
||||
g_type_name_from_instance ((GTypeInstance *) node),
|
||||
texture_id);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
cairo_surface_destroy (rendered_surface);
|
||||
@ -643,7 +645,7 @@ render_text_node (GskGLRenderer *self,
|
||||
gboolean force_color)
|
||||
{
|
||||
const PangoFont *font = gsk_text_node_peek_font (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node, NULL);
|
||||
const float text_scale = ops_get_scale (builder);
|
||||
const graphene_point_t *offset = gsk_text_node_get_offset (node);
|
||||
const guint num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
@ -1106,7 +1108,7 @@ render_linear_gradient_node (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder)
|
||||
{
|
||||
const int n_color_stops = MIN (8, gsk_linear_gradient_node_get_n_color_stops (node));
|
||||
const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node);
|
||||
const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node, NULL);
|
||||
const graphene_point_t *start = gsk_linear_gradient_node_peek_start (node);
|
||||
const graphene_point_t *end = gsk_linear_gradient_node_peek_end (node);
|
||||
OpLinearGradient *op;
|
||||
@ -3159,9 +3161,13 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
|
||||
gsk_gl_driver_create_render_target (self->gl_driver, width, height, &texture_id, &render_target);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||
"Offscreen<%s> %d", child_node->node_class->type_name, texture_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, render_target,
|
||||
"Offscreen<%s> FB %d", child_node->node_class->type_name, render_target);
|
||||
"Offscreen<%s> %d",
|
||||
g_type_name_from_instance ((GTypeInstance *) child_node),
|
||||
texture_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, render_target,
|
||||
"Offscreen<%s> FB %d",
|
||||
g_type_name_from_instance ((GTypeInstance *) child_node),
|
||||
render_target);
|
||||
|
||||
graphene_matrix_init_ortho (&item_proj,
|
||||
bounds->origin.x * scale,
|
||||
@ -3209,10 +3215,11 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
if (G_UNLIKELY (flags & DUMP_FRAMEBUFFER))
|
||||
{
|
||||
static int k;
|
||||
ops_dump_framebuffer (builder, g_strdup_printf ("%s_%p_%d.png",
|
||||
child_node->node_class->type_name,
|
||||
child_node,
|
||||
k ++),
|
||||
ops_dump_framebuffer (builder,
|
||||
g_strdup_printf ("%s_%p_%d.png",
|
||||
g_type_name_from_instance ((GTypeInstance *) child_node),
|
||||
child_node,
|
||||
k ++),
|
||||
width, height);
|
||||
}
|
||||
#endif
|
||||
@ -3583,7 +3590,9 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
gdk_gl_context_make_current (self->gl_context);
|
||||
gdk_gl_context_push_debug_group_printf (self->gl_context,
|
||||
"Render %s<%p> to texture", root->node_class->type_name, root);
|
||||
"Render %s<%p> to texture",
|
||||
g_type_name_from_instance ((GTypeInstance *) root),
|
||||
root);
|
||||
|
||||
width = ceilf (viewport->size.width);
|
||||
height = ceilf (viewport->size.height);
|
||||
@ -3595,8 +3604,11 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
glGenTextures (1, &texture_id);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||
"Texture %s<%p> %d", root->node_class->type_name, root, texture_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
|
||||
"Texture %s<%p> %d",
|
||||
g_type_name_from_instance ((GTypeInstance *) root),
|
||||
root,
|
||||
texture_id);
|
||||
|
||||
if (gdk_gl_context_get_use_es (self->gl_context))
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
@ -3605,8 +3617,11 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
glGenFramebuffers (1, &fbo_id);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, fbo_id,
|
||||
"FB %s<%p> %d", root->node_class->type_name, root, fbo_id);
|
||||
gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, fbo_id,
|
||||
"FB %s<%p> %d",
|
||||
g_type_name_from_instance ((GTypeInstance *) root),
|
||||
root,
|
||||
fbo_id);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
|
||||
g_assert_cmphex (glCheckFramebufferStatus (GL_FRAMEBUFFER), ==, GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
|
@ -46,9 +46,9 @@
|
||||
* @GSK_TEXT_NODE: A node containing a glyph string
|
||||
* @GSK_BLUR_NODE: A node that applies a blur
|
||||
* @GSK_DEBUG_NODE: Debug information that does not affect the rendering
|
||||
*
|
||||
|
||||
* The type of a node determines what the node is rendering.
|
||||
**/
|
||||
*/
|
||||
typedef enum {
|
||||
GSK_NOT_A_RENDER_NODE = 0,
|
||||
GSK_CONTAINER_NODE,
|
||||
|
@ -50,47 +50,297 @@
|
||||
|
||||
#include <gobject/gvaluecollector.h>
|
||||
|
||||
G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error)
|
||||
|
||||
#define GSK_RENDER_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_RENDER_NODE, GskRenderNodeClass))
|
||||
|
||||
/**
|
||||
* GskRenderNode: (ref-func gsk_render_node_ref) (unref-func gsk_render_node_unref)
|
||||
*
|
||||
* The `GskRenderNode` structure contains only private data.
|
||||
* A node in the render tree.
|
||||
*/
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GskRenderNode, gsk_render_node,
|
||||
gsk_render_node_ref,
|
||||
gsk_render_node_unref)
|
||||
static void
|
||||
value_render_node_init (GValue *value)
|
||||
{
|
||||
value->data[0].v_pointer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
value_render_node_free_value (GValue *value)
|
||||
{
|
||||
if (value->data[0].v_pointer != NULL)
|
||||
gsk_render_node_unref (value->data[0].v_pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
value_render_node_copy_value (const GValue *src,
|
||||
GValue *dst)
|
||||
{
|
||||
if (src->data[0].v_pointer != NULL)
|
||||
dst->data[0].v_pointer = gsk_render_node_ref (src->data[0].v_pointer);
|
||||
else
|
||||
dst->data[0].v_pointer = NULL;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
value_render_node_peek_pointer (const GValue *value)
|
||||
{
|
||||
return value->data[0].v_pointer;
|
||||
}
|
||||
|
||||
G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error)
|
||||
static char *
|
||||
value_render_node_collect_value (GValue *value,
|
||||
guint n_collect_values,
|
||||
GTypeCValue *collect_values,
|
||||
guint collect_flags)
|
||||
{
|
||||
GskRenderNode *node = collect_values[0].v_pointer;
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
value->data[0].v_pointer = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (node->parent_instance.g_class == NULL)
|
||||
return g_strconcat ("invalid unclassed GskRenderNode pointer for "
|
||||
"value type '",
|
||||
G_VALUE_TYPE_NAME (value),
|
||||
"'",
|
||||
NULL);
|
||||
|
||||
value->data[0].v_pointer = gsk_render_node_ref (node);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
value_render_node_lcopy_value (const GValue *value,
|
||||
guint n_collect_values,
|
||||
GTypeCValue *collect_values,
|
||||
guint collect_flags)
|
||||
{
|
||||
GskRenderNode **node_p = collect_values[0].v_pointer;
|
||||
|
||||
if (node_p == NULL)
|
||||
return g_strconcat ("value location for '",
|
||||
G_VALUE_TYPE_NAME (value),
|
||||
"' passed as NULL",
|
||||
NULL);
|
||||
|
||||
if (value->data[0].v_pointer == NULL)
|
||||
*node_p = NULL;
|
||||
else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
|
||||
*node_p = value->data[0].v_pointer;
|
||||
else
|
||||
*node_p = gsk_render_node_ref (value->data[0].v_pointer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_finalize (GskRenderNode *self)
|
||||
{
|
||||
self->node_class->finalize (self);
|
||||
g_type_free_instance ((GTypeInstance *) self);
|
||||
}
|
||||
|
||||
g_free (self);
|
||||
static void
|
||||
gsk_render_node_real_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_render_node_real_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_real_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_class_init (GskRenderNodeClass *klass)
|
||||
{
|
||||
klass->node_type = GSK_NOT_A_RENDER_NODE;
|
||||
klass->finalize = gsk_render_node_finalize;
|
||||
klass->draw = gsk_render_node_real_draw;
|
||||
klass->can_diff = gsk_render_node_real_can_diff;
|
||||
klass->diff = gsk_render_node_real_diff;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_init (GskRenderNode *self)
|
||||
{
|
||||
g_atomic_ref_count_init (&self->ref_count);
|
||||
}
|
||||
|
||||
GType
|
||||
gsk_render_node_get_type (void)
|
||||
{
|
||||
static volatile gsize render_node_type__volatile;
|
||||
|
||||
if (g_once_init_enter (&render_node_type__volatile))
|
||||
{
|
||||
static const GTypeFundamentalInfo finfo = {
|
||||
(G_TYPE_FLAG_CLASSED |
|
||||
G_TYPE_FLAG_INSTANTIATABLE |
|
||||
G_TYPE_FLAG_DERIVABLE |
|
||||
G_TYPE_FLAG_DEEP_DERIVABLE),
|
||||
};
|
||||
|
||||
static const GTypeValueTable value_table = {
|
||||
value_render_node_init,
|
||||
value_render_node_free_value,
|
||||
value_render_node_copy_value,
|
||||
value_render_node_peek_pointer,
|
||||
"p",
|
||||
value_render_node_collect_value,
|
||||
"p",
|
||||
value_render_node_lcopy_value,
|
||||
};
|
||||
|
||||
const GTypeInfo node_info = {
|
||||
/* Class */
|
||||
sizeof (GskRenderNodeClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gsk_render_node_class_init,
|
||||
(GClassFinalizeFunc) NULL,
|
||||
NULL,
|
||||
|
||||
/* Instance */
|
||||
sizeof (GskRenderNode),
|
||||
0,
|
||||
(GInstanceInitFunc) gsk_render_node_init,
|
||||
|
||||
/* GValue */
|
||||
&value_table,
|
||||
};
|
||||
|
||||
GType render_node_type =
|
||||
g_type_register_fundamental (g_type_fundamental_next (),
|
||||
g_intern_static_string ("GskRenderNode"),
|
||||
&node_info, &finfo,
|
||||
G_TYPE_FLAG_ABSTRACT);
|
||||
|
||||
g_once_init_leave (&render_node_type__volatile, render_node_type);
|
||||
}
|
||||
|
||||
return render_node_type__volatile;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GskRenderNodeType node_type;
|
||||
|
||||
void (* finalize) (GskRenderNode *node);
|
||||
void (* draw) (GskRenderNode *node,
|
||||
cairo_t *cr);
|
||||
gboolean (* can_diff) (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2);
|
||||
void (* diff) (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
} RenderNodeClassData;
|
||||
|
||||
static void
|
||||
gsk_render_node_generic_class_init (gpointer g_class,
|
||||
gpointer class_data)
|
||||
{
|
||||
GskRenderNodeClass *node_class = g_class;
|
||||
RenderNodeClassData *node_data = class_data;
|
||||
|
||||
/* Mandatory */
|
||||
node_class->node_type = node_data->node_type;
|
||||
|
||||
/* Optional */
|
||||
if (node_data->finalize != NULL)
|
||||
node_class->finalize = node_data->finalize;
|
||||
if (node_data->can_diff != NULL)
|
||||
node_class->can_diff = node_data->can_diff;
|
||||
|
||||
/* Mandatory */
|
||||
node_class->draw = node_data->draw;
|
||||
node_class->diff = node_data->diff;
|
||||
|
||||
g_free (node_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_render_node_can_diff_true (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gsk_render_node_new:
|
||||
* @node_class: class structure for this node
|
||||
* gsk_render_node_type_register_static:
|
||||
* @node_name: the name of the node
|
||||
* @node_info: type information of the node
|
||||
*
|
||||
* Returns: (transfer full): the newly created #GskRenderNode
|
||||
* Registers a new #GskRenderNode type for the given @node_name using
|
||||
* the type information in @node_info.
|
||||
*
|
||||
* Returns: the newly registered GType
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size)
|
||||
GType
|
||||
gsk_render_node_type_register_static (const char *node_name,
|
||||
const GskRenderNodeTypeInfo *node_info)
|
||||
{
|
||||
GskRenderNode *self;
|
||||
GTypeInfo info;
|
||||
|
||||
g_return_val_if_fail (node_class != NULL, NULL);
|
||||
g_return_val_if_fail (node_class->node_type != GSK_NOT_A_RENDER_NODE, NULL);
|
||||
info.class_size = sizeof (GskRenderNodeClass);
|
||||
info.base_init = NULL;
|
||||
info.base_finalize = NULL;
|
||||
info.class_init = gsk_render_node_generic_class_init;
|
||||
info.class_finalize = NULL;
|
||||
|
||||
self = g_malloc0 (node_class->struct_size + extra_size);
|
||||
/* Avoid having a class_init() and a class struct for every GskRenderNode,
|
||||
* by passing the various virtual functions and class data when initializing
|
||||
* the base class
|
||||
*/
|
||||
info.class_data = g_new (RenderNodeClassData, 1);
|
||||
((RenderNodeClassData *) info.class_data)->node_type = node_info->node_type;
|
||||
((RenderNodeClassData *) info.class_data)->finalize = node_info->finalize;
|
||||
((RenderNodeClassData *) info.class_data)->draw = node_info->draw;
|
||||
((RenderNodeClassData *) info.class_data)->can_diff = node_info->can_diff != NULL
|
||||
? node_info->can_diff
|
||||
: gsk_render_node_can_diff_true;
|
||||
((RenderNodeClassData *) info.class_data)->diff = node_info->diff != NULL
|
||||
? node_info->diff
|
||||
: gsk_render_node_diff_impossible;
|
||||
|
||||
self->node_class = node_class;
|
||||
info.instance_size = node_info->instance_size;
|
||||
info.n_preallocs = 0;
|
||||
info.instance_init = (GInstanceInitFunc) node_info->instance_init;
|
||||
info.value_table = NULL;
|
||||
|
||||
self->ref_count = 1;
|
||||
return g_type_register_static (GSK_TYPE_RENDER_NODE, node_name, &info, 0);
|
||||
}
|
||||
|
||||
return self;
|
||||
/*< private >
|
||||
* gsk_render_node_alloc:
|
||||
* @node_type: the #GskRenderNodeType to instantiate
|
||||
*
|
||||
* Instantiates a new #GskRenderNode for the given @node_type.
|
||||
*
|
||||
* Returns: (transfer full) (type GskRenderNode): the newly created #GskRenderNode
|
||||
*/
|
||||
gpointer
|
||||
gsk_render_node_alloc (GskRenderNodeType node_type)
|
||||
{
|
||||
g_return_val_if_fail (node_type > GSK_NOT_A_RENDER_NODE, NULL);
|
||||
g_return_val_if_fail (node_type < GSK_RENDER_NODE_TYPE_N_TYPES, NULL);
|
||||
|
||||
g_assert (gsk_render_node_types[node_type] != G_TYPE_INVALID);
|
||||
return g_type_create_instance (gsk_render_node_types[node_type]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +356,7 @@ gsk_render_node_ref (GskRenderNode *node)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||
|
||||
g_atomic_int_inc (&node->ref_count);
|
||||
g_atomic_ref_count_inc (&node->ref_count);
|
||||
|
||||
return node;
|
||||
}
|
||||
@ -125,10 +375,11 @@ gsk_render_node_unref (GskRenderNode *node)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_RENDER_NODE (node));
|
||||
|
||||
if (g_atomic_int_dec_and_test (&node->ref_count))
|
||||
gsk_render_node_finalize (node);
|
||||
if (g_atomic_ref_count_dec (&node->ref_count))
|
||||
GSK_RENDER_NODE_GET_CLASS (node)->finalize (node);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gsk_render_node_get_node_type:
|
||||
* @node: a #GskRenderNode
|
||||
@ -142,14 +393,14 @@ gsk_render_node_get_node_type (GskRenderNode *node)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), GSK_NOT_A_RENDER_NODE);
|
||||
|
||||
return node->node_class->node_type;
|
||||
return GSK_RENDER_NODE_GET_CLASS (node)->node_type;
|
||||
}
|
||||
|
||||
G_GNUC_PURE static inline
|
||||
GskRenderNodeType
|
||||
_gsk_render_node_get_node_type (const GskRenderNode *node)
|
||||
{
|
||||
return node->node_class->node_type;
|
||||
return GSK_RENDER_NODE_GET_CLASS (node)->node_type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,9 +446,10 @@ gsk_render_node_draw (GskRenderNode *node,
|
||||
cairo_save (cr);
|
||||
|
||||
GSK_NOTE (CAIRO, g_message ("Rendering node %s[%p]",
|
||||
node->node_class->type_name, node));
|
||||
g_type_name_from_instance ((GTypeInstance *) node),
|
||||
node));
|
||||
|
||||
node->node_class->draw (node, cr);
|
||||
GSK_RENDER_NODE_GET_CLASS (node)->draw (node, cr);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_DEBUG_CHECK (GEOMETRY))
|
||||
@ -216,7 +468,7 @@ gsk_render_node_draw (GskRenderNode *node,
|
||||
if (cairo_status (cr))
|
||||
{
|
||||
g_warning ("drawing failure for render node %s: %s",
|
||||
node->node_class->type_name,
|
||||
g_type_name_from_instance ((GTypeInstance *) node),
|
||||
cairo_status_to_string (cairo_status (cr)));
|
||||
}
|
||||
}
|
||||
@ -245,7 +497,7 @@ gsk_render_node_can_diff (const GskRenderNode *node1,
|
||||
if (_gsk_render_node_get_node_type (node1) != _gsk_render_node_get_node_type (node2))
|
||||
return FALSE;
|
||||
|
||||
return node1->node_class->can_diff (node1, node2);
|
||||
return GSK_RENDER_NODE_GET_CLASS (node1)->can_diff (node1, node2);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -299,7 +551,7 @@ gsk_render_node_diff (GskRenderNode *node1,
|
||||
if (_gsk_render_node_get_node_type (node1) != _gsk_render_node_get_node_type (node2))
|
||||
return gsk_render_node_diff_impossible (node1, node2, region);
|
||||
|
||||
return node1->node_class->diff (node1, node2, region);
|
||||
return GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, region);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,6 +99,53 @@ GskRenderNode * gsk_render_node_deserialize (GBytes
|
||||
GskParseErrorFunc error_func,
|
||||
gpointer user_data);
|
||||
|
||||
#define GSK_TYPE_DEBUG_NODE (gsk_render_node_types[GSK_DEBUG_NODE])
|
||||
#define GSK_TYPE_COLOR_NODE (gsk_render_node_types[GSK_COLOR_NODE])
|
||||
#define GSK_TYPE_TEXTURE_NODE (gsk_render_node_types[GSK_TEXTURE_NODE])
|
||||
#define GSK_TYPE_LINEAR_GRADIENT_NODE (gsk_render_node_types[GSK_LINEAR_GRADIENT_NODE])
|
||||
#define GSK_TYPE_REPEATING_LINEAR_GRADIENT_NODE (gsk_render_node_types[GSK_REPEATING_LINEAR_GRADIENT_NODE])
|
||||
#define GSK_TYPE_BORDER_NODE (gsk_render_node_types[GSK_BORDER_NODE])
|
||||
#define GSK_TYPE_INSET_SHADOW_NODE (gsk_render_node_types[GSK_INSET_SHADOW_NODE])
|
||||
#define GSK_TYPE_OUTSET_SHADOW_NODE (gsk_render_node_types[GSK_OUTSET_SHADOW_NODE])
|
||||
#define GSK_TYPE_CAIRO_NODE (gsk_render_node_types[GSK_CAIRO_NODE])
|
||||
#define GSK_TYPE_CONTAINER_NODE (gsk_render_node_types[GSK_CONTAINER_NODE])
|
||||
#define GSK_TYPE_TRANSFORM_NODE (gsk_render_node_types[GSK_TRANSFORM_NODE])
|
||||
#define GSK_TYPE_OPACITY_NODE (gsk_render_node_types[GSK_OPACITY_NODE])
|
||||
#define GSK_TYPE_COLOR_MATRIX_NODE (gsk_render_node_types[GSK_COLOR_MATRIX_NODE])
|
||||
#define GSK_TYPE_REPEAT_NODE (gsk_render_node_types[GSK_REPEAT_NODE])
|
||||
#define GSK_TYPE_CLIP_NODE (gsk_render_node_types[GSK_CLIP_NODE])
|
||||
#define GSK_TYPE_ROUNDED_CLIP_NODE (gsk_render_node_types[GSK_ROUNDED_CLIP_NODE])
|
||||
#define GSK_TYPE_SHADOW_NODE (gsk_render_node_types[GSK_SHADOW_NODE])
|
||||
#define GSK_TYPE_BLEND_NODE (gsk_render_node_types[GSK_BLEND_NODE])
|
||||
#define GSK_TYPE_CROSS_FADE_NODE (gsk_render_node_types[GSK_CROSS_FADE_NODE])
|
||||
#define GSK_TYPE_TEXT_NODE (gsk_render_node_types[GSK_TEXT_NODE])
|
||||
#define GSK_TYPE_BLUR_NODE (gsk_render_node_types[GSK_BLUR_NODE])
|
||||
|
||||
/*< private >*/
|
||||
GDK_EXTERN_VAR GType gsk_render_node_types[];
|
||||
|
||||
typedef struct _GskDebugNode GskDebugNode;
|
||||
typedef struct _GskColorNode GskColorNode;
|
||||
typedef struct _GskTextureNode GskTextureNode;
|
||||
typedef struct _GskLinearGradientNode GskLinearGradientNode;
|
||||
typedef struct _GskRepeatingLinearGradientNode GskRepeatingLinearGradientNode;
|
||||
typedef struct _GskBorderNode GskBorderNode;
|
||||
typedef struct _GskInsetShadowNode GskInsetShadowNode;
|
||||
typedef struct _GskOutsetShadowNode GskOutsetShadowNode;
|
||||
typedef struct _GskCairoNode GskCairoNode;
|
||||
typedef struct _GskContainerNode GskContainerNode;
|
||||
typedef struct _GskTransformNode GskTransformNode;
|
||||
typedef struct _GskOpacityNode GskOpacityNode;
|
||||
typedef struct _GskColorMatrixNode GskColorMatrixNode;
|
||||
typedef struct _GskRepeatNode GskRepeatNode;
|
||||
typedef struct _GskClipNode GskClipNode;
|
||||
typedef struct _GskRoundedClipNode GskRoundedClipNode;
|
||||
typedef struct _GskShadowNode GskShadowNode;
|
||||
typedef struct _GskBlendNode GskBlendNode;
|
||||
typedef struct _GskCrossFadeNode GskCrossFadeNode;
|
||||
typedef struct _GskTextNode GskTextNode;
|
||||
typedef struct _GskBlurNode GskBlurNode;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_debug_node_new (GskRenderNode *child,
|
||||
char *message);
|
||||
@ -132,7 +179,8 @@ const graphene_point_t * gsk_linear_gradient_node_peek_end (GskRenderNo
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gsize gsk_linear_gradient_node_get_n_color_stops (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const GskColorStop * gsk_linear_gradient_node_peek_color_stops (GskRenderNode *node);
|
||||
const GskColorStop * gsk_linear_gradient_node_peek_color_stops (GskRenderNode *node,
|
||||
gsize *n_stops);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds,
|
||||
@ -152,7 +200,6 @@ const float * gsk_border_node_peek_widths (GskRenderNode
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const GdkRGBA * gsk_border_node_peek_colors (GskRenderNode *node);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_inset_shadow_node_new (const GskRoundedRect *outline,
|
||||
const GdkRGBA *color,
|
||||
@ -254,7 +301,6 @@ GskRenderNode * gsk_clip_node_get_child (GskRenderNode
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const graphene_rect_t * gsk_clip_node_peek_clip (GskRenderNode *node);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_rounded_clip_node_new (GskRenderNode *child,
|
||||
const GskRoundedRect *clip);
|
||||
@ -308,7 +354,8 @@ gboolean gsk_text_node_has_color_glyphs (GskRenderNode
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gsk_text_node_get_num_glyphs (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const PangoGlyphInfo *gsk_text_node_peek_glyphs (GskRenderNode *node);
|
||||
const PangoGlyphInfo *gsk_text_node_peek_glyphs (GskRenderNode *node,
|
||||
guint *n_glyphs);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const GdkRGBA * gsk_text_node_peek_color (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1973,9 +1973,9 @@ render_node_print (Printer *p,
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
{
|
||||
const guint n_stops = gsk_linear_gradient_node_get_n_color_stops (node);
|
||||
const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node);
|
||||
int i;
|
||||
const gsize n_stops = gsk_linear_gradient_node_get_n_color_stops (node);
|
||||
const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node, NULL);
|
||||
gsize i;
|
||||
|
||||
if (gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE)
|
||||
start_node (p, "repeating-linear-gradient");
|
||||
@ -2229,7 +2229,7 @@ render_node_print (Printer *p,
|
||||
case GSK_TEXT_NODE:
|
||||
{
|
||||
const guint n_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node, NULL);
|
||||
const graphene_point_t *offset = gsk_text_node_get_offset (node);
|
||||
const GdkRGBA *color = gsk_text_node_peek_color (node);
|
||||
PangoFont *font = gsk_text_node_peek_font (node);
|
||||
@ -2449,7 +2449,7 @@ render_node_print (Printer *p,
|
||||
break;
|
||||
|
||||
default:
|
||||
g_error ("Unhandled node: %s", node->node_class->type_name);
|
||||
g_error ("Unhandled node: %s", g_type_name_from_instance ((GTypeInstance *) node));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8,22 +8,30 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskRenderNodeClass GskRenderNodeClass;
|
||||
|
||||
#define GSK_IS_RENDER_NODE_TYPE(node,type) (GSK_IS_RENDER_NODE (node) && (node)->node_class->node_type == (type))
|
||||
/* Keep this in sync with the GskRenderNodeType enumeration.
|
||||
*
|
||||
* We don't add an "n-types" value to avoid having to handle
|
||||
* it in every single switch.
|
||||
*/
|
||||
#define GSK_RENDER_NODE_TYPE_N_TYPES (GSK_DEBUG_NODE + 1)
|
||||
|
||||
#define GSK_IS_RENDER_NODE_TYPE(node,type) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((node), GSK_TYPE_RENDER_NODE, GskRenderNodeClass)->node_type == (type))
|
||||
|
||||
struct _GskRenderNode
|
||||
{
|
||||
const GskRenderNodeClass *node_class;
|
||||
GTypeInstance parent_instance;
|
||||
|
||||
volatile int ref_count;
|
||||
gatomicrefcount ref_count;
|
||||
|
||||
graphene_rect_t bounds;
|
||||
};
|
||||
|
||||
struct _GskRenderNodeClass
|
||||
{
|
||||
GTypeClass parent_class;
|
||||
|
||||
GskRenderNodeType node_type;
|
||||
gsize struct_size;
|
||||
const char *type_name;
|
||||
|
||||
void (* finalize) (GskRenderNode *node);
|
||||
void (* draw) (GskRenderNode *node,
|
||||
@ -35,18 +43,54 @@ struct _GskRenderNodeClass
|
||||
cairo_region_t *region);
|
||||
};
|
||||
|
||||
GskRenderNode * gsk_render_node_new (const GskRenderNodeClass *node_class,
|
||||
gsize extra_size);
|
||||
/*< private >
|
||||
* GskRenderNodeTypeInfo:
|
||||
* @node_type: the render node type in the #GskRenderNodeType enumeration
|
||||
* @instance_size: the size of the render node instance
|
||||
* @instance_init: (nullable): the instance initialization function
|
||||
* @finalize: (nullable): the instance finalization function; must chain up to the
|
||||
* implementation of the parent class
|
||||
* @draw: the function called by gsk_render_node_draw()
|
||||
* @can_diff: (nullable): the function called by gsk_render_node_can_diff(); if
|
||||
* unset, gsk_render_node_can_diff_true() will be used
|
||||
* @diff: (nullable): the function called by gsk_render_node_diff(); if unset,
|
||||
* gsk_render_node_diff_impossible() will be used
|
||||
*
|
||||
* A struction that contains the type information for a #GskRenderNode subclass,
|
||||
* to be used by gsk_render_node_type_register_static().
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GskRenderNodeType node_type;
|
||||
|
||||
gboolean gsk_render_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2) G_GNUC_PURE;
|
||||
void gsk_render_node_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
void gsk_render_node_diff_impossible (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
gsize instance_size;
|
||||
|
||||
void (* instance_init) (GskRenderNode *node);
|
||||
void (* finalize) (GskRenderNode *node);
|
||||
void (* draw) (GskRenderNode *node,
|
||||
cairo_t *cr);
|
||||
gboolean (* can_diff) (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2);
|
||||
void (* diff) (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
} GskRenderNodeTypeInfo;
|
||||
|
||||
void gsk_render_node_init_types (void);
|
||||
|
||||
GType gsk_render_node_type_register_static (const char *node_name,
|
||||
const GskRenderNodeTypeInfo *node_info);
|
||||
|
||||
gpointer gsk_render_node_alloc (GskRenderNodeType node_type);
|
||||
|
||||
gboolean gsk_render_node_can_diff (const GskRenderNode *node1,
|
||||
const GskRenderNode *node2) G_GNUC_PURE;
|
||||
void gsk_render_node_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
void gsk_render_node_diff_impossible (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
cairo_region_t *region);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -258,7 +258,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
return;
|
||||
case GSK_SHADOW_NODE:
|
||||
default:
|
||||
FALLBACK ("Unsupported node '%s'", node->node_class->type_name);
|
||||
FALLBACK ("Unsupported node '%s'", g_type_name_from_instance ((GTypeInstance *) node));
|
||||
|
||||
case GSK_REPEAT_NODE:
|
||||
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
|
||||
@ -346,7 +346,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
case GSK_TEXT_NODE:
|
||||
{
|
||||
const PangoFont *font = gsk_text_node_peek_font (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node, NULL);
|
||||
guint num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
gboolean has_color_glyphs = gsk_text_node_has_color_glyphs (node);
|
||||
int i;
|
||||
@ -817,7 +817,7 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
|
||||
g_message ("Upload op=%s, node %s[%p], bounds %gx%g",
|
||||
op->type == GSK_VULKAN_OP_FALLBACK_CLIP ? "fallback-clip" :
|
||||
(op->type == GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP ? "fallback-rounded-clip" : "fallback"),
|
||||
node->node_class->type_name, node,
|
||||
g_type_name_from_instance ((GTypeInstance *) node), node,
|
||||
ceil (node->bounds.size.width),
|
||||
ceil (node->bounds.size.height)));
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@ -1195,7 +1195,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
&op->text.node->bounds,
|
||||
(PangoFont *)gsk_text_node_peek_font (op->text.node),
|
||||
gsk_text_node_get_num_glyphs (op->text.node),
|
||||
gsk_text_node_peek_glyphs (op->text.node),
|
||||
gsk_text_node_peek_glyphs (op->text.node, NULL),
|
||||
gsk_text_node_peek_color (op->text.node),
|
||||
gsk_text_node_get_offset (op->text.node),
|
||||
op->text.start_glyph,
|
||||
@ -1214,7 +1214,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
&op->text.node->bounds,
|
||||
(PangoFont *)gsk_text_node_peek_font (op->text.node),
|
||||
gsk_text_node_get_num_glyphs (op->text.node),
|
||||
gsk_text_node_peek_glyphs (op->text.node),
|
||||
gsk_text_node_peek_glyphs (op->text.node, NULL),
|
||||
gsk_text_node_get_offset (op->text.node),
|
||||
op->text.start_glyph,
|
||||
op->text.num_glyphs,
|
||||
@ -1244,7 +1244,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
||||
gsk_linear_gradient_node_peek_end (op->render.node),
|
||||
gsk_render_node_get_node_type (op->render.node) == GSK_REPEATING_LINEAR_GRADIENT_NODE,
|
||||
gsk_linear_gradient_node_get_n_color_stops (op->render.node),
|
||||
gsk_linear_gradient_node_peek_color_stops (op->render.node));
|
||||
gsk_linear_gradient_node_peek_color_stops (op->render.node, NULL));
|
||||
n_bytes += op->render.vertex_count;
|
||||
}
|
||||
break;
|
||||
|
@ -95,6 +95,7 @@
|
||||
#include "gdk/gdk.h"
|
||||
#include "gdk/gdk-private.h"
|
||||
#include "gsk/gskprivate.h"
|
||||
#include "gsk/gskrendernodeprivate.h"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
@ -660,6 +661,7 @@ do_post_parse_initialization (void)
|
||||
gtk_widget_set_default_direction (gtk_get_locale_direction ());
|
||||
|
||||
gsk_ensure_resources ();
|
||||
gsk_render_node_init_types ();
|
||||
_gtk_ensure_resources ();
|
||||
|
||||
gtk_initialized = TRUE;
|
||||
|
@ -601,7 +601,7 @@ populate_render_node_properties (GtkListStore *store,
|
||||
const graphene_point_t *start = gsk_linear_gradient_node_peek_start (node);
|
||||
const graphene_point_t *end = gsk_linear_gradient_node_peek_end (node);
|
||||
const gsize n_stops = gsk_linear_gradient_node_get_n_color_stops (node);
|
||||
const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node);
|
||||
const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node, NULL);
|
||||
int i;
|
||||
GString *s;
|
||||
GdkTexture *texture;
|
||||
@ -633,7 +633,7 @@ populate_render_node_properties (GtkListStore *store,
|
||||
case GSK_TEXT_NODE:
|
||||
{
|
||||
const PangoFont *font = gsk_text_node_peek_font (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node, NULL);
|
||||
const GdkRGBA *color = gsk_text_node_peek_color (node);
|
||||
guint num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
const graphene_point_t *offset = gsk_text_node_get_offset (node);
|
||||
|
Loading…
Reference in New Issue
Block a user