diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2016-08-12 16:44:29 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2016-08-12 16:44:29 +0100 |
commit | e6c37c8e83799475be9025366e34c6385e47b1c1 (patch) | |
tree | ed2579f04228ce52ac559ee2e8ece0ad5e1ef180 | |
parent | 0dd2328361971b1a6dcc580e6b29719b33857bd9 (diff) | |
download | gtk+-e6c37c8e83799475be9025366e34c6385e47b1c1.tar.gz |
gsk: Allow adding a GL texture as a node content
If we already have a GL texture we definitely don't want to use
gdk_cairo_draw_from_gl() to draw on a Cairo context if we're going
to take the Cairo surface to which we draw and put it into an OpenGL
texture.
-rw-r--r-- | gsk/gskglrenderer.c | 42 | ||||
-rw-r--r-- | gsk/gskrendernode.c | 42 | ||||
-rw-r--r-- | gsk/gskrendernode.h | 4 | ||||
-rw-r--r-- | gsk/gskrendernodeprivate.h | 10 |
4 files changed, 80 insertions, 18 deletions
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c index c343f4c91c..4d5c4f3698 100644 --- a/gsk/gskglrenderer.c +++ b/gsk/gskglrenderer.c @@ -602,7 +602,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self, RenderItem *parent) { graphene_rect_t viewport; - cairo_surface_t *surface; GskRenderNodeIter iter; graphene_matrix_t mv; graphene_rect_t bounds; @@ -705,22 +704,31 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self, item.children = NULL; } - surface = gsk_render_node_get_surface (node); - - /* If the node does not draw anything, we skip it */ - if (surface == NULL && item.render_data.render_target_id == self->texture_id) - goto out; - - /* Upload the Cairo surface to a GL texture */ - item.render_data.texture_id = gsk_gl_driver_create_texture (self->gl_driver, - item.size.width, - item.size.height); - gsk_gl_driver_bind_source_texture (self->gl_driver, item.render_data.texture_id); - gsk_gl_driver_init_texture_with_surface (self->gl_driver, - item.render_data.texture_id, - surface, - self->gl_min_filter, - self->gl_mag_filter); + if (gsk_render_node_has_texture (node)) + { + item.render_data.texture_id = gsk_render_node_get_texture (node); + } + else if (gsk_render_node_has_surface (node)) + { + cairo_surface_t *surface = gsk_render_node_get_surface (node); + + /* Upload the Cairo surface to a GL texture */ + item.render_data.texture_id = gsk_gl_driver_create_texture (self->gl_driver, + item.size.width, + item.size.height); + gsk_gl_driver_bind_source_texture (self->gl_driver, item.render_data.texture_id); + gsk_gl_driver_init_texture_with_surface (self->gl_driver, + item.render_data.texture_id, + surface, + self->gl_min_filter, + self->gl_mag_filter); + } + else + { + /* If the node does not draw anything, we skip it */ + if (item.render_data.render_target_id == self->texture_id) + goto out; + } /* Create the vertex buffers holding the geometry of the quad */ { diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c index 1ec296e6f3..c39480ee13 100644 --- a/gsk/gskrendernode.c +++ b/gsk/gskrendernode.c @@ -1186,6 +1186,48 @@ gsk_render_node_update_world_matrix (GskRenderNode *node, gsk_render_node_update_world_matrix (child, TRUE); } +gboolean +gsk_render_node_has_surface (GskRenderNode *node) +{ + g_return_val_if_fail (GSK_IS_RENDER_NODE (node), FALSE); + + return node->surface != NULL; +} + +gboolean +gsk_render_node_has_texture (GskRenderNode *node) +{ + g_return_val_if_fail (GSK_IS_RENDER_NODE (node), FALSE); + + return node->texture_id != 0; +} + +int +gsk_render_node_get_texture (GskRenderNode *node) +{ + g_return_val_if_fail (GSK_IS_RENDER_NODE (node), 0); + + return node->texture_id; +} + +/** + * gsk_render_node_set_texture: + * @node: a #GskRenderNode + * @texture_id: the object id of a GL texture + * + * Associates a @texture_id to a #GskRenderNode. + * + * Since: 3.22 + */ +void +gsk_render_node_set_texture (GskRenderNode *node, + int texture_id) +{ + g_return_if_fail (GSK_IS_RENDER_NODE (node)); + + node->texture_id = texture_id; +} + /*< private > * gsk_render_node_get_surface: * @node: a #GskRenderNode diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h index afeab20219..d597ea7163 100644 --- a/gsk/gskrendernode.h +++ b/gsk/gskrendernode.h @@ -120,6 +120,10 @@ GDK_AVAILABLE_IN_3_22 GskBlendMode gsk_render_node_get_blend_mode (GskRenderNode *node); GDK_AVAILABLE_IN_3_22 +void gsk_render_node_set_texture (GskRenderNode *node, + int texture_id); + +GDK_AVAILABLE_IN_3_22 int gsk_render_node_get_scale_factor (GskRenderNode *node); GDK_AVAILABLE_IN_3_22 diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h index 85cb2b839e..84ee2f08fd 100644 --- a/gsk/gskrendernodeprivate.h +++ b/gsk/gskrendernodeprivate.h @@ -35,9 +35,12 @@ struct _GskRenderNode /* Tag updated when adding/removing children */ gint64 age; - /* The contents of the node */ + /* The contents of the node as a Cairo surface */ cairo_surface_t *surface; + /* The contents of the node as a GL surface */ + int texture_id; + /* Paint opacity */ double opacity; @@ -82,6 +85,11 @@ double gsk_render_node_get_opacity (GskRenderNode *node); cairo_surface_t *gsk_render_node_get_surface (GskRenderNode *node); +int gsk_render_node_get_texture (GskRenderNode *node); + +gboolean gsk_render_node_has_surface (GskRenderNode *node); +gboolean gsk_render_node_has_texture (GskRenderNode *node); + GskRenderNode *gsk_render_node_get_toplevel (GskRenderNode *node); void gsk_render_node_update_world_matrix (GskRenderNode *node, |