From 9e1004da0c8330c3d2f407f89097d034fecee787 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Fri, 11 Sep 2020 18:32:25 -0300 Subject: [PATCH] cogl/matrix-stack: Use graphene APIs This one is a bit tricky. The tl;dr; is that switching from right-hand multiplication to left-hand multiplication required applying the stack from left to root. This actually allowed simplifying the code a bit, since CoglMatrixEntry only stores a pointer to its parent, and that's all we need to know for left-hand multiplication. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439 --- cogl/cogl/cogl-matrix-stack.c | 202 ++++++++++++++-------------------- 1 file changed, 81 insertions(+), 121 deletions(-) diff --git a/cogl/cogl/cogl-matrix-stack.c b/cogl/cogl/cogl-matrix-stack.c index 9a308ea7b..b978c51a0 100644 --- a/cogl/cogl/cogl-matrix-stack.c +++ b/cogl/cogl/cogl-matrix-stack.c @@ -238,10 +238,10 @@ cogl_matrix_stack_frustum (CoglMatrixStack *stack, _cogl_matrix_stack_push_replacement_entry (stack, COGL_MATRIX_OP_LOAD); - cogl_matrix_init_identity (&entry->matrix); - cogl_matrix_frustum (&entry->matrix, - left, right, bottom, top, - z_near, z_far); + graphene_matrix_init_frustum (&entry->matrix, + left, right, + bottom, top, + z_near, z_far); } void @@ -256,9 +256,9 @@ cogl_matrix_stack_perspective (CoglMatrixStack *stack, entry = _cogl_matrix_stack_push_replacement_entry (stack, COGL_MATRIX_OP_LOAD); - cogl_matrix_init_identity (&entry->matrix); - cogl_matrix_perspective (&entry->matrix, - fov_y, aspect, z_near, z_far); + graphene_matrix_init_perspective (&entry->matrix, + fov_y, aspect, + z_near, z_far); } void @@ -275,9 +275,10 @@ cogl_matrix_stack_orthographic (CoglMatrixStack *stack, entry = _cogl_matrix_stack_push_replacement_entry (stack, COGL_MATRIX_OP_LOAD); - cogl_matrix_init_identity (&entry->matrix); - cogl_matrix_orthographic (&entry->matrix, - x_1, y_1, x_2, y_2, near, far); + graphene_matrix_init_ortho (&entry->matrix, + x_1, x_2, + y_2, y_1, + near, far); } void @@ -372,44 +373,94 @@ graphene_matrix_t * cogl_matrix_entry_get (CoglMatrixEntry *entry, graphene_matrix_t *matrix) { - int depth; CoglMatrixEntry *current; - CoglMatrixEntry **children; - int i; + int depth; - for (depth = 0, current = entry; + graphene_matrix_init_identity (matrix); + + for (current = entry, depth = 0; current; current = current->parent, depth++) { switch (current->op) { + case COGL_MATRIX_OP_TRANSLATE: + { + CoglMatrixEntryTranslate *translate = + (CoglMatrixEntryTranslate *) current; + graphene_matrix_translate (matrix, &translate->translate); + break; + } + case COGL_MATRIX_OP_ROTATE: + { + CoglMatrixEntryRotate *rotate = + (CoglMatrixEntryRotate *) current; + graphene_matrix_rotate (matrix, rotate->angle, &rotate->axis); + break; + } + case COGL_MATRIX_OP_ROTATE_EULER: + { + CoglMatrixEntryRotateEuler *rotate = + (CoglMatrixEntryRotateEuler *) current; + graphene_matrix_rotate_euler (matrix, &rotate->euler); + break; + } + case COGL_MATRIX_OP_SCALE: + { + CoglMatrixEntryScale *scale = + (CoglMatrixEntryScale *) current; + graphene_matrix_scale (matrix, scale->x, scale->y, scale->z); + break; + } + case COGL_MATRIX_OP_MULTIPLY: + { + CoglMatrixEntryMultiply *multiply = + (CoglMatrixEntryMultiply *) current; + graphene_matrix_multiply (matrix, &multiply->matrix, matrix); + break; + } + case COGL_MATRIX_OP_LOAD_IDENTITY: - cogl_matrix_init_identity (matrix); - goto initialized; + goto applied; + case COGL_MATRIX_OP_LOAD: { - CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)current; - _cogl_matrix_init_from_matrix_without_inverse (matrix, - &load->matrix); - goto initialized; + CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *) current; + graphene_matrix_multiply (matrix, &load->matrix, matrix); + goto applied; } case COGL_MATRIX_OP_SAVE: { - CoglMatrixEntrySave *save = (CoglMatrixEntrySave *)current; + CoglMatrixEntrySave *save = (CoglMatrixEntrySave *) current; if (!save->cache_valid) { cogl_matrix_entry_get (current->parent, &save->cache); save->cache_valid = TRUE; } - _cogl_matrix_init_from_matrix_without_inverse (matrix, &save->cache); - goto initialized; + graphene_matrix_multiply (matrix, &save->cache, matrix); + goto applied; } - default: - continue; } } -initialized: +applied: + +#ifdef COGL_ENABLE_DEBUG + if (!current) + { + g_warning ("Inconsistent matrix stack"); + return NULL; + } + + entry->composite_gets++; + + if (COGL_DEBUG_ENABLED (COGL_DEBUG_PERFORMANCE) && + entry->composite_gets >= 2) + { + COGL_NOTE (PERFORMANCE, + "Re-composing a matrix stack entry multiple times"); + } +#endif if (depth == 0) { @@ -438,97 +489,6 @@ initialized: return NULL; } -#ifdef COGL_ENABLE_DEBUG - if (!current) - { - g_warning ("Inconsistent matrix stack"); - return NULL; - } - - entry->composite_gets++; -#endif - - children = g_alloca (sizeof (CoglMatrixEntry) * depth); - - /* We need walk the list of entries from the init/load/save entry - * back towards the leaf node but the nodes don't link to their - * children so we need to re-walk them here to add to a separate - * array. */ - for (i = depth - 1, current = entry; - i >= 0 && current; - i--, current = current->parent) - { - children[i] = current; - } - -#ifdef COGL_ENABLE_DEBUG - if (COGL_DEBUG_ENABLED (COGL_DEBUG_PERFORMANCE) && - entry->composite_gets >= 2) - { - COGL_NOTE (PERFORMANCE, - "Re-composing a matrix stack entry multiple times"); - } -#endif - - for (i = 0; i < depth; i++) - { - switch (children[i]->op) - { - case COGL_MATRIX_OP_TRANSLATE: - { - CoglMatrixEntryTranslate *translate = - (CoglMatrixEntryTranslate *)children[i]; - cogl_matrix_translate (matrix, - translate->translate.x, - translate->translate.y, - translate->translate.z); - continue; - } - case COGL_MATRIX_OP_ROTATE: - { - CoglMatrixEntryRotate *rotate= - (CoglMatrixEntryRotate *)children[i]; - cogl_matrix_rotate (matrix, - rotate->angle, - graphene_vec3_get_x (&rotate->axis), - graphene_vec3_get_y (&rotate->axis), - graphene_vec3_get_z (&rotate->axis)); - continue; - } - case COGL_MATRIX_OP_ROTATE_EULER: - { - CoglMatrixEntryRotateEuler *rotate = - (CoglMatrixEntryRotateEuler *)children[i]; - cogl_matrix_rotate_euler (matrix, - &rotate->euler); - continue; - } - case COGL_MATRIX_OP_SCALE: - { - CoglMatrixEntryScale *scale = - (CoglMatrixEntryScale *)children[i]; - cogl_matrix_scale (matrix, - scale->x, - scale->y, - scale->z); - continue; - } - case COGL_MATRIX_OP_MULTIPLY: - { - CoglMatrixEntryMultiply *multiply = - (CoglMatrixEntryMultiply *)children[i]; - cogl_matrix_multiply (matrix, matrix, &multiply->matrix); - continue; - } - - case COGL_MATRIX_OP_LOAD_IDENTITY: - case COGL_MATRIX_OP_LOAD: - case COGL_MATRIX_OP_SAVE: - g_warn_if_reached (); - continue; - } - } - return NULL; } @@ -793,7 +753,7 @@ cogl_matrix_entry_equal (CoglMatrixEntry *entry0, { CoglMatrixEntryMultiply *mult0 = (CoglMatrixEntryMultiply *)entry0; CoglMatrixEntryMultiply *mult1 = (CoglMatrixEntryMultiply *)entry1; - if (!cogl_matrix_equal (&mult0->matrix, &mult1->matrix)) + if (!graphene_matrix_equal (&mult0->matrix, &mult1->matrix)) return FALSE; } break; @@ -804,7 +764,7 @@ cogl_matrix_entry_equal (CoglMatrixEntry *entry0, /* There's no need to check any further since an * _OP_LOAD makes all the ancestors redundant as far as * the final matrix value is concerned. */ - return cogl_matrix_equal (&load0->matrix, &load1->matrix); + return graphene_matrix_equal (&load0->matrix, &load1->matrix); } case COGL_MATRIX_OP_SAVE: /* We skip over saves above so we shouldn't see save entries */ @@ -890,14 +850,14 @@ cogl_debug_matrix_entry_print (CoglMatrixEntry *entry) { CoglMatrixEntryMultiply *mult = (CoglMatrixEntryMultiply *)entry; g_print (" MULT:\n"); - _cogl_matrix_prefix_print (" ", &mult->matrix); + graphene_matrix_print (&mult->matrix); continue; } case COGL_MATRIX_OP_LOAD: { CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)entry; g_print (" LOAD:\n"); - _cogl_matrix_prefix_print (" ", &load->matrix); + graphene_matrix_print (&load->matrix); continue; } case COGL_MATRIX_OP_SAVE: