[gtk+] gsk: Allow adding a GL texture as a node content
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] gsk: Allow adding a GL texture as a node content
- Date: Tue, 18 Oct 2016 11:00:29 +0000 (UTC)
commit 3bdd9c270afd15e7a983b8a5d703dbc7404dd9fb
Author: Emmanuele Bassi <ebassi gnome org>
Date: Fri Aug 12 16:44:29 2016 +0100
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.
gsk/gskglrenderer.c | 42 +++++++++++++++++++++++++-----------------
gsk/gskrendernode.c | 42 ++++++++++++++++++++++++++++++++++++++++++
gsk/gskrendernode.h | 4 ++++
gsk/gskrendernodeprivate.h | 10 +++++++++-
4 files changed, 80 insertions(+), 18 deletions(-)
---
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c
index c343f4c..4d5c4f3 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 1ec296e..c39480e 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 afeab20..d597ea7 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 85cb2b8..84ee2f0 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,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]