[clutter/wip/faster-pango-1.6: 1/2] cogl-pango-display-list: Use CoglPrimitive instead of CoglVertexBuffer



commit 40bd7226cfa9faefcfc1b57a13803d51804b99d9
Author: Neil Roberts <neil linux intel com>
Date:   Thu Aug 11 12:48:56 2011 +0100

    cogl-pango-display-list: Use CoglPrimitive instead of CoglVertexBuffer
    
    When rendering text through a VBO, CoglPangoDisplayList now uses the
    CoglPrimitive API instead of CoglVertexBuffer. CoglVertexBuffer is
    just a layer on top of the attirbute buffer API anyway so it should be
    slightly faster.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=656303

 clutter/cogl/pango/cogl-pango-display-list.c |  143 ++++++++++++++------------
 1 files changed, 76 insertions(+), 67 deletions(-)
---
diff --git a/clutter/cogl/pango/cogl-pango-display-list.c b/clutter/cogl/pango/cogl-pango-display-list.c
index 6226a81..dd06387 100644
--- a/clutter/cogl/pango/cogl-pango-display-list.c
+++ b/clutter/cogl/pango/cogl-pango-display-list.c
@@ -39,7 +39,6 @@ typedef enum
 } CoglPangoDisplayListNodeType;
 
 typedef struct _CoglPangoDisplayListNode CoglPangoDisplayListNode;
-typedef struct _CoglPangoDisplayListVertex CoglPangoDisplayListVertex;
 
 struct _CoglPangoDisplayList
 {
@@ -64,8 +63,8 @@ struct _CoglPangoDisplayListNode
       CoglHandle  texture;
       /* Array of vertex data to render out of this texture */
       GArray     *verts;
-      /* A VBO representing those vertices */
-      CoglHandle  vertex_buffer;
+      /* A primitive representing those vertices */
+      CoglPrimitive *primitive;
     } texture;
 
     struct
@@ -86,11 +85,6 @@ struct _CoglPangoDisplayListNode
   } d;
 };
 
-struct _CoglPangoDisplayListVertex
-{
-  float x, y, t_x, t_y;
-};
-
 CoglPangoDisplayList *
 _cogl_pango_display_list_new (void)
 {
@@ -130,7 +124,7 @@ _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl,
                                       float tx_2, float ty_2)
 {
   CoglPangoDisplayListNode *node;
-  CoglPangoDisplayListVertex *verts;
+  CoglVertexP2T2 *verts;
 
   /* Add to the last node if it is a texture node with the same
      target texture */
@@ -142,10 +136,10 @@ _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl,
           : !node->color_override))
     {
       /* Get rid of the vertex buffer so that it will be recreated */
-      if (node->d.texture.vertex_buffer != COGL_INVALID_HANDLE)
+      if (node->d.texture.primitive != NULL)
         {
-          cogl_handle_unref (node->d.texture.vertex_buffer);
-          node->d.texture.vertex_buffer = COGL_INVALID_HANDLE;
+          cogl_object_unref (node->d.texture.primitive);
+          node->d.texture.primitive = NULL;
         }
     }
   else
@@ -158,8 +152,8 @@ _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl,
       node->color = dl->color;
       node->d.texture.texture = cogl_handle_ref (texture);
       node->d.texture.verts
-        = g_array_new (FALSE, FALSE, sizeof (CoglPangoDisplayListVertex));
-      node->d.texture.vertex_buffer = COGL_INVALID_HANDLE;
+        = g_array_new (FALSE, FALSE, sizeof (CoglVertexP2T2));
+      node->d.texture.primitive = NULL;
 
       _cogl_pango_display_list_append_node (dl, node);
     }
@@ -167,28 +161,28 @@ _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl,
   g_array_set_size (node->d.texture.verts,
                     node->d.texture.verts->len + 4);
   verts = &g_array_index (node->d.texture.verts,
-                          CoglPangoDisplayListVertex,
+                          CoglVertexP2T2,
                           node->d.texture.verts->len - 4);
 
   verts->x = x_1;
   verts->y = y_1;
-  verts->t_x = tx_1;
-  verts->t_y = ty_1;
+  verts->s = tx_1;
+  verts->t = ty_1;
   verts++;
   verts->x = x_1;
   verts->y = y_2;
-  verts->t_x = tx_1;
-  verts->t_y = ty_2;
+  verts->s = tx_1;
+  verts->t = ty_2;
   verts++;
   verts->x = x_2;
   verts->y = y_2;
-  verts->t_x = tx_2;
-  verts->t_y = ty_2;
+  verts->s = tx_2;
+  verts->t = ty_2;
   verts++;
   verts->x = x_2;
   verts->y = y_1;
-  verts->t_x = tx_2;
-  verts->t_y = ty_1;
+  verts->s = tx_2;
+  verts->t = ty_1;
 }
 
 void
@@ -240,15 +234,15 @@ emit_rectangles_through_journal (CoglPangoDisplayListNode *node)
 
   for (i = 0; i < node->d.texture.verts->len; i += 4)
     {
-      CoglPangoDisplayListVertex *v0 =
+      CoglVertexP2T2 *v0 =
         &g_array_index (node->d.texture.verts,
-                        CoglPangoDisplayListVertex, i);
-      CoglPangoDisplayListVertex *v1 =
+                        CoglVertexP2T2, i);
+      CoglVertexP2T2 *v1 =
         &g_array_index (node->d.texture.verts,
-                        CoglPangoDisplayListVertex, i + 2);
+                        CoglVertexP2T2, i + 2);
       cogl_rectangle_with_texture_coords (v0->x, v0->y, v1->x, v1->y,
-                                          v0->t_x, v0->t_y,
-                                          v1->t_x, v1->t_y);
+                                          v0->s, v0->t,
+                                          v1->s, v1->t);
     }
 }
 
@@ -263,49 +257,64 @@ emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node)
    * be re-used avoiding the repeated cost of validating the data and
    * mapping it into the GPU... */
 
-  if (node->d.texture.vertex_buffer == COGL_INVALID_HANDLE)
+  if (node->d.texture.primitive == NULL)
     {
-      CoglHandle vb = cogl_vertex_buffer_new (node->d.texture.verts->len);
-
-      cogl_vertex_buffer_add (vb, "gl_Vertex", 2,
-                              COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
-                              sizeof (CoglPangoDisplayListVertex),
-                              &g_array_index (node->d.texture.verts,
-                                              CoglPangoDisplayListVertex, 0).x);
-      cogl_vertex_buffer_add (vb, "gl_MultiTexCoord0", 2,
-                              COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
-                              sizeof (CoglPangoDisplayListVertex),
-                              &g_array_index (node->d.texture.verts,
-                                              CoglPangoDisplayListVertex,
-                                              0).t_x);
-      cogl_vertex_buffer_submit (vb);
-
-      node->d.texture.vertex_buffer = vb;
-    }
-
+      CoglVertexArray *buffer;
+      CoglAttribute *attributes[3];
+      CoglPrimitive *prim;
+
+      buffer
+        = cogl_vertex_array_new (node->d.texture.verts->len
+                                 * sizeof (CoglVertexP2T2),
+                                 node->d.texture.verts->data);
+      attributes[0] = cogl_attribute_new (buffer,
+                                          "cogl_position_in",
+                                          sizeof (CoglVertexP2T2),
+                                          G_STRUCT_OFFSET (CoglVertexP2T2, x),
+                                          2, /* n_components */
+                                          COGL_ATTRIBUTE_TYPE_FLOAT);
+      attributes[1] = cogl_attribute_new (buffer,
+                                          "cogl_tex_coord0_in",
+                                          sizeof (CoglVertexP2T2),
+                                          G_STRUCT_OFFSET (CoglVertexP2T2, s),
+                                          2, /* n_components */
+                                          COGL_ATTRIBUTE_TYPE_FLOAT);
+      attributes[2] = NULL;
+
+      prim = cogl_primitive_new_with_attributes_array
+        (COGL_VERTICES_MODE_TRIANGLES,
+         node->d.texture.verts->len,
+         attributes);
 
 #ifdef CLUTTER_COGL_HAS_GL
 
-  cogl_vertex_buffer_draw (node->d.texture.vertex_buffer,
-                           GL_QUADS,
-                           0, node->d.texture.verts->len);
+      cogl_primitive_set_mode (prim, GL_QUADS);
 
 #else /* CLUTTER_COGL_HAS_GL */
-  {
-    /* GLES doesn't support GL_QUADS so instead we use a VBO with
-       indexed vertices to generate GL_TRIANGLES from the quads */
-
-    int n_indices = node->d.texture.verts->len / 4 * 6;
-    CoglHandle indices_vbo
-      = cogl_vertex_buffer_indices_get_for_quads (n_indices);
-
-    cogl_vertex_buffer_draw_elements (node->d.texture.vertex_buffer,
-                                      COGL_VERTICES_MODE_TRIANGLES,
-                                      indices_vbo,
-                                      0, node->d.texture.verts->len - 1,
-                                      0, n_indices);
-  }
+
+      {
+        /* GLES doesn't support GL_QUADS so instead we use a VBO
+           with indexed vertices to generate GL_TRIANGLES from the
+           quads */
+
+        CoglIndices *indices =
+          cogl_get_rectangle_indices (node->d.texture.verts->len / 4);
+
+        cogl_primitive_set_indices (prim, indices);
+        cogl_primitive_set_n_vertices (prim,
+                                       node->d.texture.verts->len / 4 * 6);
+      }
+
 #endif /* CLUTTER_COGL_HAS_GL */
+
+      node->d.texture.primitive = prim;
+
+      cogl_object_unref (buffer);
+      cogl_object_unref (attributes[0]);
+      cogl_object_unref (attributes[1]);
+    }
+
+  cogl_primitive_draw (node->d.texture.primitive);
 }
 
 static void
@@ -410,8 +419,8 @@ _cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node)
       g_array_free (node->d.texture.verts, TRUE);
       if (node->d.texture.texture != COGL_INVALID_HANDLE)
         cogl_handle_unref (node->d.texture.texture);
-      if (node->d.texture.vertex_buffer != COGL_INVALID_HANDLE)
-        cogl_handle_unref (node->d.texture.vertex_buffer);
+      if (node->d.texture.primitive != NULL)
+        cogl_object_unref (node->d.texture.primitive);
     }
 
   g_slice_free (CoglPangoDisplayListNode, node);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]