summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2016-08-12 16:44:29 +0100
committerEmmanuele Bassi <ebassi@gnome.org>2016-08-12 16:44:29 +0100
commite6c37c8e83799475be9025366e34c6385e47b1c1 (patch)
treeed2579f04228ce52ac559ee2e8ece0ad5e1ef180
parent0dd2328361971b1a6dcc580e6b29719b33857bd9 (diff)
downloadgtk+-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.c42
-rw-r--r--gsk/gskrendernode.c42
-rw-r--r--gsk/gskrendernode.h4
-rw-r--r--gsk/gskrendernodeprivate.h10
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,