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
This commit is contained in:
Georges Basile Stavracas Neto 2020-09-11 18:32:25 -03:00
parent d03ffe1e97
commit 9e1004da0c

View File

@ -238,10 +238,10 @@ cogl_matrix_stack_frustum (CoglMatrixStack *stack,
_cogl_matrix_stack_push_replacement_entry (stack, _cogl_matrix_stack_push_replacement_entry (stack,
COGL_MATRIX_OP_LOAD); COGL_MATRIX_OP_LOAD);
cogl_matrix_init_identity (&entry->matrix); graphene_matrix_init_frustum (&entry->matrix,
cogl_matrix_frustum (&entry->matrix, left, right,
left, right, bottom, top, bottom, top,
z_near, z_far); z_near, z_far);
} }
void void
@ -256,9 +256,9 @@ cogl_matrix_stack_perspective (CoglMatrixStack *stack,
entry = entry =
_cogl_matrix_stack_push_replacement_entry (stack, _cogl_matrix_stack_push_replacement_entry (stack,
COGL_MATRIX_OP_LOAD); COGL_MATRIX_OP_LOAD);
cogl_matrix_init_identity (&entry->matrix); graphene_matrix_init_perspective (&entry->matrix,
cogl_matrix_perspective (&entry->matrix, fov_y, aspect,
fov_y, aspect, z_near, z_far); z_near, z_far);
} }
void void
@ -275,9 +275,10 @@ cogl_matrix_stack_orthographic (CoglMatrixStack *stack,
entry = entry =
_cogl_matrix_stack_push_replacement_entry (stack, _cogl_matrix_stack_push_replacement_entry (stack,
COGL_MATRIX_OP_LOAD); COGL_MATRIX_OP_LOAD);
cogl_matrix_init_identity (&entry->matrix); graphene_matrix_init_ortho (&entry->matrix,
cogl_matrix_orthographic (&entry->matrix, x_1, x_2,
x_1, y_1, x_2, y_2, near, far); y_2, y_1,
near, far);
} }
void void
@ -372,44 +373,94 @@ graphene_matrix_t *
cogl_matrix_entry_get (CoglMatrixEntry *entry, cogl_matrix_entry_get (CoglMatrixEntry *entry,
graphene_matrix_t *matrix) graphene_matrix_t *matrix)
{ {
int depth;
CoglMatrixEntry *current; CoglMatrixEntry *current;
CoglMatrixEntry **children; int depth;
int i;
for (depth = 0, current = entry; graphene_matrix_init_identity (matrix);
for (current = entry, depth = 0;
current; current;
current = current->parent, depth++) current = current->parent, depth++)
{ {
switch (current->op) 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: case COGL_MATRIX_OP_LOAD_IDENTITY:
cogl_matrix_init_identity (matrix); goto applied;
goto initialized;
case COGL_MATRIX_OP_LOAD: case COGL_MATRIX_OP_LOAD:
{ {
CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)current; CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *) current;
_cogl_matrix_init_from_matrix_without_inverse (matrix, graphene_matrix_multiply (matrix, &load->matrix, matrix);
&load->matrix); goto applied;
goto initialized;
} }
case COGL_MATRIX_OP_SAVE: case COGL_MATRIX_OP_SAVE:
{ {
CoglMatrixEntrySave *save = (CoglMatrixEntrySave *)current; CoglMatrixEntrySave *save = (CoglMatrixEntrySave *) current;
if (!save->cache_valid) if (!save->cache_valid)
{ {
cogl_matrix_entry_get (current->parent, &save->cache); cogl_matrix_entry_get (current->parent, &save->cache);
save->cache_valid = TRUE; save->cache_valid = TRUE;
} }
_cogl_matrix_init_from_matrix_without_inverse (matrix, &save->cache); graphene_matrix_multiply (matrix, &save->cache, matrix);
goto initialized; 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) if (depth == 0)
{ {
@ -438,97 +489,6 @@ initialized:
return NULL; 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; return NULL;
} }
@ -793,7 +753,7 @@ cogl_matrix_entry_equal (CoglMatrixEntry *entry0,
{ {
CoglMatrixEntryMultiply *mult0 = (CoglMatrixEntryMultiply *)entry0; CoglMatrixEntryMultiply *mult0 = (CoglMatrixEntryMultiply *)entry0;
CoglMatrixEntryMultiply *mult1 = (CoglMatrixEntryMultiply *)entry1; CoglMatrixEntryMultiply *mult1 = (CoglMatrixEntryMultiply *)entry1;
if (!cogl_matrix_equal (&mult0->matrix, &mult1->matrix)) if (!graphene_matrix_equal (&mult0->matrix, &mult1->matrix))
return FALSE; return FALSE;
} }
break; break;
@ -804,7 +764,7 @@ cogl_matrix_entry_equal (CoglMatrixEntry *entry0,
/* There's no need to check any further since an /* There's no need to check any further since an
* _OP_LOAD makes all the ancestors redundant as far as * _OP_LOAD makes all the ancestors redundant as far as
* the final matrix value is concerned. */ * 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: case COGL_MATRIX_OP_SAVE:
/* We skip over saves above so we shouldn't see save entries */ /* 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; CoglMatrixEntryMultiply *mult = (CoglMatrixEntryMultiply *)entry;
g_print (" MULT:\n"); g_print (" MULT:\n");
_cogl_matrix_prefix_print (" ", &mult->matrix); graphene_matrix_print (&mult->matrix);
continue; continue;
} }
case COGL_MATRIX_OP_LOAD: case COGL_MATRIX_OP_LOAD:
{ {
CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)entry; CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)entry;
g_print (" LOAD:\n"); g_print (" LOAD:\n");
_cogl_matrix_prefix_print (" ", &load->matrix); graphene_matrix_print (&load->matrix);
continue; continue;
} }
case COGL_MATRIX_OP_SAVE: case COGL_MATRIX_OP_SAVE: