[gtk+/wip/ebassi/gsk-renderer] gsk: Allow adding a GL texture as a node content



commit e6c37c8e83799475be9025366e34c6385e47b1c1
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]