gsk: Tie render nodes to renderers

Render nodes need access to rendering information like scaling factors.
If we keep render nodes separate from renderers until we submit a nodes
tree for rendering we're going to have to duplicate all that information
in a way that makes the API more complicated and fuzzier on its
semantics.

By having GskRenderer create GskRenderNode instances we can tie nodes
and renderers together; since higher layers will also have access to
the renderer instance, this does not add any burden to callers.

Additionally, if memory measurements indicate that we are spending too
much time in the allocation of new render nodes, we can now easily
implement a free-list or a renderer-specific allocator without breaking
the API.
This commit is contained in:
Emmanuele Bassi 2016-07-27 16:23:44 +01:00
parent ab8420ec52
commit 3d90a070d5
7 changed files with 41 additions and 11 deletions

View File

@ -921,6 +921,7 @@ gsk_renderer_render (GskRenderer *renderer,
g_return_if_fail (GDK_IS_DRAWING_CONTEXT (context));
g_return_if_fail (priv->drawing_context == NULL);
g_return_if_fail (priv->root_node == NULL);
g_return_if_fail (root->renderer == renderer);
priv->drawing_context = g_object_ref (context);
priv->root_node = gsk_render_node_ref (root);
@ -1034,6 +1035,24 @@ gsk_renderer_get_use_alpha (GskRenderer *renderer)
return priv->use_alpha;
}
/**
* gsk_renderer_create_render_node:
* @renderer: a #GskRenderer
*
* Creates a new #GskRenderNode instance tied to the given @renderer.
*
* Returns: (transfer full): the new #GskRenderNode
*
* Since: 3.22
*/
GskRenderNode *
gsk_renderer_create_render_node (GskRenderer *renderer)
{
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
return gsk_render_node_new (renderer);
}
/**
* gsk_renderer_get_for_display:
* @display: a #GdkDisplay

View File

@ -96,6 +96,10 @@ GDK_AVAILABLE_IN_3_22
gboolean gsk_renderer_realize (GskRenderer *renderer);
GDK_AVAILABLE_IN_3_22
void gsk_renderer_unrealize (GskRenderer *renderer);
GDK_AVAILABLE_IN_3_22
GskRenderNode * gsk_renderer_create_render_node (GskRenderer *renderer);
GDK_AVAILABLE_IN_3_22
void gsk_renderer_render (GskRenderer *renderer,
GskRenderNode *root,

View File

@ -233,19 +233,22 @@ gsk_render_node_get_type (void)
return gsk_render_node_type__volatile;
}
/**
/*< private >
* gsk_render_node_new:
* @renderer: a #GskRenderer
*
* Creates a new #GskRenderNode, to be used with #GskRenderer.
* Creates a new #GskRenderNode, to be used with a #GskRenderer.
*
* Returns: (transfer full): the newly created #GskRenderNode
*
* Since: 3.22
*/
GskRenderNode *
gsk_render_node_new (void)
gsk_render_node_new (GskRenderer *renderer)
{
return (GskRenderNode *) g_type_create_instance (GSK_TYPE_RENDER_NODE);
GskRenderNode *res = (GskRenderNode *) g_type_create_instance (GSK_TYPE_RENDER_NODE);
res->renderer = renderer;
return res;
}
/**

View File

@ -38,8 +38,6 @@ typedef struct _GskRenderNodeClass GskRenderNodeClass;
GDK_AVAILABLE_IN_3_22
GType gsk_render_node_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_22
GskRenderNode * gsk_render_node_new (void);
GDK_AVAILABLE_IN_3_22
GskRenderNode * gsk_render_node_ref (GskRenderNode *node);
GDK_AVAILABLE_IN_3_22

View File

@ -2,6 +2,7 @@
#define __GSK_RENDER_NODE_PRIVATE_H__
#include "gskrendernode.h"
#include "gskrenderer.h"
#include <cairo.h>
G_BEGIN_DECLS
@ -16,6 +17,9 @@ struct _GskRenderNode
volatile int ref_count;
/* Back pointer to the renderer that created the node */
GskRenderer *renderer;
/* The graph */
GskRenderNode *parent;
GskRenderNode *first_child;
@ -68,6 +72,8 @@ struct _GskRenderNodeClass
void (* finalize) (GskRenderNode *node);
};
GskRenderNode *gsk_render_node_new (GskRenderer *renderer);
void gsk_render_node_make_immutable (GskRenderNode *node);
void gsk_render_node_get_bounds (GskRenderNode *node,

View File

@ -15859,7 +15859,7 @@ gtk_widget_get_render_node (GtkWidget *widget,
GskRenderNode *tmp;
cairo_t *cr;
tmp = gsk_render_node_new ();
tmp = gsk_renderer_create_render_node (renderer);
gsk_render_node_set_name (tmp, "Draw Fallback");
gsk_render_node_set_bounds (tmp, &bounds);
gsk_render_node_set_transform (tmp, &m);
@ -15882,7 +15882,7 @@ gtk_widget_get_render_node (GtkWidget *widget,
gboolean result;
cairo_t *cr;
tmp = gsk_render_node_new ();
tmp = gsk_renderer_create_render_node (renderer);
gsk_render_node_set_name (tmp, "Draw Signal Handler");
gsk_render_node_set_bounds (tmp, &bounds);
gsk_render_node_set_transform (tmp, &m);

View File

@ -9597,7 +9597,7 @@ gtk_window_get_render_node (GtkWidget *widget,
graphene_rect_init (&bounds, allocation.x, allocation.y, allocation.width, allocation.height);
graphene_matrix_init_translate (&m, graphene_point3d_init (&p, allocation.x, allocation.y, 0.));
node = gsk_render_node_new ();
node = gsk_renderer_create_render_node (renderer);
gsk_render_node_set_name (node, "Window Decoration");
gsk_render_node_set_bounds (node, &bounds);
gsk_render_node_set_transform (node, &m);