[mutter/gbsneto/graphene-matrix: 17/73] cogl/matrix: Multiply using graphene matrices




commit 02a30f2a22b42f76682dc8b78acfb2049988295e
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Sep 10 10:34:15 2020 -0300

    cogl/matrix: Multiply using graphene matrices
    
    At this point, we are still only changing CoglMatrix APIs internally, and
    it should still produce the same output as before.
    
    To achieve this, using graphens matrix implementation, we need to exploit
    some knowledge about conventions used in Cogl and graphene respectively.
    
    In Cogl, transformation matrices are equivalent to those of affine
    transformation matrices. The convention used by graphene, however, is to
    operate on matrices that are transposed compared to their affine
    counterparts.
    
    So for example, let's say we want to multiply the affine matrices A and B,
    to get C.
    
      A × B = C
    
    The first step is to convert A and B to graphene matrices. We do this by
    importing the floating point array, importing it directly using graphene.
    
    Cogl exports its matrix to a column major floating point array. When we
    import this in graphene, being row major, we end up with the same matrix,
    only transposed.
    
    Cogl       Graphene
    
      A   <===>   Aᵀ
      B   <===>   Bᵀ
    
    We then multiply these imported matrices in reverse
    
      Bᵀ × Aᵀ
    
    which in turn, due to ABᵀ = BᵀAᵀ, gives us
    
      Bᵀ × Aᵀ = (A × B)ᵀ
    
    Our original goal was to find C, thus we know that
    
      A × B = C
    
    That means we can shuffle things around a bit.
    
      A × B = C
    
      Bᵀ × Aᵀ = (A × B)ᵀ
    
      Bᵀ × Aᵀ = Cᵀ
    
    With the same conversion as done when going from Cogl to graphene, only
    the other way around, we still end up effectively transposing the matrix
    during the conversion.
    
    Graphene      Cogl
    
       Cᵀ  <===>   C
    
    Thus when converting Cᵀ to Cogl, we in fact end up with C.
    
    (Explanation authored by Jonas Ådahl)
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439

 cogl/cogl/cogl-matrix.c | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)
---
diff --git a/cogl/cogl/cogl-matrix.c b/cogl/cogl/cogl-matrix.c
index 4f65b16cf9..d191bed9e9 100644
--- a/cogl/cogl/cogl-matrix.c
+++ b/cogl/cogl/cogl-matrix.c
@@ -326,32 +326,22 @@ matrix_multiply_array_with_flags (CoglMatrix *result,
     matrix_multiply4x4 ((float *)result, (float *)result, array);
 }
 
-/* Joins both flags and marks the type and inverse as dirty.  Calls
- * matrix_multiply3x4() if both matrices are 3D, or matrix_multiply4x4()
- * otherwise.
- */
-static void
-_cogl_matrix_multiply (CoglMatrix *result,
-                       const CoglMatrix *a,
-                       const CoglMatrix *b)
-{
-  result->flags = (a->flags |
-                   b->flags |
-                   MAT_DIRTY_TYPE |
-                   MAT_DIRTY_INVERSE);
-
-  if (TEST_MAT_FLAGS(result, MAT_FLAGS_3D))
-    matrix_multiply3x4 ((float *)result, (float *)a, (float *)b);
-  else
-    matrix_multiply4x4 ((float *)result, (float *)a, (float *)b);
-}
-
 void
 cogl_matrix_multiply (CoglMatrix *result,
                      const CoglMatrix *a,
                      const CoglMatrix *b)
 {
-  _cogl_matrix_multiply (result, a, b);
+  graphene_matrix_t res;
+  graphene_matrix_t ma;
+  graphene_matrix_t mb;
+
+  cogl_matrix_to_graphene_matrix (a, &ma);
+  cogl_matrix_to_graphene_matrix (b, &mb);
+  graphene_matrix_multiply (&mb, &ma, &res);
+  graphene_matrix_to_cogl_matrix (&res, result);
+
+  result->flags = a->flags | b->flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE;
+
   _COGL_MATRIX_DEBUG_PRINT (result);
 }
 


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