util: optimize _clutter_util_fully_transform_vertices
authorRobert Bragg <robert@linux.intel.com>
Tue, 8 Feb 2011 10:37:15 +0000 (10:37 +0000)
committerRobert Bragg <robert@linux.intel.com>
Mon, 7 Mar 2011 13:26:20 +0000 (13:26 +0000)
Instead of unconditionally combining the modelview and projection
matrices and then iterating each of the vertices to call
cogl_matrix_transform_point for each one in turn we now only combine the
matrices if there are more than 4 vertices (with less than 4 vertices
its less work to transform them separately) and we use the new
cogl_vertex_{transform,project}_points APIs which can hopefully
vectorize the transformations.

Finally the perspective divide and viewport scale is done in a separate
loop at the end and we don't do the spurious perspective divide and
viewport scale for the z component.

clutter/clutter-util.c
clutter/cogl/cogl/cogl-matrix.c
clutter/cogl/cogl/cogl-matrix.h

index a45d00f..9793f7d 100644 (file)
@@ -81,6 +81,14 @@ _clutter_gettext (const gchar *str)
 #define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
 #define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2)))
 
+typedef struct _ClutterVertex4
+{
+  float x;
+  float y;
+  float z;
+  float w;
+} ClutterVertex4;
+
 void
 _clutter_util_fully_transform_vertices (const CoglMatrix *modelview,
                                         const CoglMatrix *projection,
@@ -90,31 +98,53 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview,
                                         int n_vertices)
 {
   CoglMatrix modelview_projection;
+  ClutterVertex4 *vertices_tmp;
   int i;
 
-  /* XXX: we should find a way to cache this per actor */
-  cogl_matrix_multiply (&modelview_projection,
-                        projection,
-                        modelview);
+  vertices_tmp = g_alloca (sizeof (ClutterVertex4) * n_vertices);
+
+  if (n_vertices >= 4)
+    {
+      /* XXX: we should find a way to cache this per actor */
+      cogl_matrix_multiply (&modelview_projection,
+                            projection,
+                            modelview);
+      cogl_matrix_project_points (&modelview_projection,
+                                  3,
+                                  sizeof (ClutterVertex),
+                                  vertices_in,
+                                  sizeof (ClutterVertex4),
+                                  vertices_tmp,
+                                  n_vertices);
+    }
+  else
+    {
+      cogl_matrix_transform_points (modelview,
+                                    3,
+                                    sizeof (ClutterVertex),
+                                    vertices_in,
+                                    sizeof (ClutterVertex4),
+                                    vertices_tmp,
+                                    n_vertices);
+
+      cogl_matrix_project_points (projection,
+                                  3,
+                                  sizeof (ClutterVertex4),
+                                  vertices_tmp,
+                                  sizeof (ClutterVertex4),
+                                  vertices_tmp,
+                                  n_vertices);
+    }
 
   for (i = 0; i < n_vertices; i++)
     {
-      const ClutterVertex *vertex_in = &vertices_in[i];
+      ClutterVertex4 vertex_tmp = vertices_tmp[i];
       ClutterVertex *vertex_out = &vertices_out[i];
-      gfloat x, y, z, w;
-
-      x = vertex_in->x;
-      y = vertex_in->y;
-      z = vertex_in->z;
-      w = 1.0;
-
-      /* Transform the point using the modelview matrix */
-      cogl_matrix_transform_point (&modelview_projection, &x, &y, &z, &w);
-
       /* Finally translate from OpenGL coords to window coords */
-      vertex_out->x = MTX_GL_SCALE_X (x, w, viewport[2], viewport[0]);
-      vertex_out->y = MTX_GL_SCALE_Y (y, w, viewport[3], viewport[1]);
-      vertex_out->z = MTX_GL_SCALE_Z (z, w, viewport[2], viewport[0]);
+      vertex_out->x = MTX_GL_SCALE_X (vertex_tmp.x, vertex_tmp.w,
+                                      viewport[2], viewport[0]);
+      vertex_out->y = MTX_GL_SCALE_Y (vertex_tmp.y, vertex_tmp.w,
+                                      viewport[3], viewport[1]);
     }
 }
 
index 344b67d..625b89f 100644 (file)
@@ -498,7 +498,7 @@ typedef struct _Point4f
 static void
 _cogl_matrix_transform_points_f2 (const CoglMatrix *matrix,
                                   size_t stride_in,
-                                  void *points_in,
+                                  const void *points_in,
                                   size_t stride_out,
                                   void *points_out,
                                   int n_points)
@@ -519,7 +519,7 @@ _cogl_matrix_transform_points_f2 (const CoglMatrix *matrix,
 static void
 _cogl_matrix_project_points_f2 (const CoglMatrix *matrix,
                                 size_t stride_in,
-                                void *points_in,
+                                const void *points_in,
                                 size_t stride_out,
                                 void *points_out,
                                 int n_points)
@@ -541,7 +541,7 @@ _cogl_matrix_project_points_f2 (const CoglMatrix *matrix,
 static void
 _cogl_matrix_transform_points_f3 (const CoglMatrix *matrix,
                                   size_t stride_in,
-                                  void *points_in,
+                                  const void *points_in,
                                   size_t stride_out,
                                   void *points_out,
                                   int n_points)
@@ -565,7 +565,7 @@ _cogl_matrix_transform_points_f3 (const CoglMatrix *matrix,
 static void
 _cogl_matrix_project_points_f3 (const CoglMatrix *matrix,
                                 size_t stride_in,
-                                void *points_in,
+                                const void *points_in,
                                 size_t stride_out,
                                 void *points_out,
                                 int n_points)
@@ -591,7 +591,7 @@ _cogl_matrix_project_points_f3 (const CoglMatrix *matrix,
 static void
 _cogl_matrix_project_points_f4 (const CoglMatrix *matrix,
                                 size_t stride_in,
-                                void *points_in,
+                                const void *points_in,
                                 size_t stride_out,
                                 void *points_out,
                                 int n_points)
@@ -618,7 +618,7 @@ void
 cogl_matrix_transform_points (const CoglMatrix *matrix,
                               int n_components,
                               size_t stride_in,
-                              void *points_in,
+                              const void *points_in,
                               size_t stride_out,
                               void *points_out,
                               int n_points)
@@ -646,7 +646,7 @@ void
 cogl_matrix_project_points (const CoglMatrix *matrix,
                             int n_components,
                             size_t stride_in,
-                            void *points_in,
+                            const void *points_in,
                             size_t stride_out,
                             void *points_out,
                             int n_points)
index c5d5987..1db1d8f 100644 (file)
@@ -505,7 +505,7 @@ void
 cogl_matrix_transform_points (const CoglMatrix *matrix,
                               int n_components,
                               size_t stride_in,
-                              void *points_in,
+                              const void *points_in,
                               size_t stride_out,
                               void *points_out,
                               int n_points);
@@ -560,7 +560,7 @@ void
 cogl_matrix_project_points (const CoglMatrix *matrix,
                             int n_components,
                             size_t stride_in,
-                            void *points_in,
+                            const void *points_in,
                             size_t stride_out,
                             void *points_out,
                             int n_points);