snapshot: Fix merging color matrix nodes

The code was appliying the matrices in the wrong order: we have to apply
the inner node's matrix first, and the outer one second. Due to the
matrices being implicitly transposed, the matrix multiplication was done
in the right order, yet the wrong matrix was being mutliplied by the
wrong offset vector.

To make the code a little easier to follow, create explicit variables
for the resulting matrix and offset (instead of reusing matrix2 and
offset2), and fix & expand the comment to document how matrix
transposition factors into this.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
This commit is contained in:
Sergey Bugaev
2023-08-15 11:03:25 +03:00
committed by Matthias Clasen
parent 294bc262cd
commit 582d368653

View File

@@ -558,29 +558,29 @@ merge_color_matrix_nodes (const graphene_matrix_t *matrix2,
const graphene_vec4_t *offset2,
GskRenderNode *child)
{
const graphene_matrix_t *mat1 = gsk_color_matrix_node_get_color_matrix (child);
const graphene_matrix_t *matrix1 = gsk_color_matrix_node_get_color_matrix (child);
const graphene_vec4_t *offset1 = gsk_color_matrix_node_get_color_offset (child);
graphene_matrix_t mat2 = *matrix2;
graphene_vec4_t off2 = *offset2;
graphene_matrix_t matrix;
graphene_vec4_t offset;
GskRenderNode *result;
g_assert (gsk_render_node_get_node_type (child) == GSK_COLOR_MATRIX_NODE);
/* color matrix node: color = mat * p + offset; for a pixel p.
* color = mat1 * (mat2 * p + offset2) + offset1;
* = mat1 * mat2 * p + offset2 * mat1 + offset1
* = (mat1 * mat2) * p + (offset2 * mat1 + offset1)
/* color matrix node: color = trans(mat) * p + offset; for a pixel p.
* color = trans(mat2) * (trans(mat1) * p + offset1) + offset2
* = trans(mat2) * trans(mat1) * p + trans(mat2) * offset1 + offset2
* = trans(mat1 * mat2) * p + (trans(mat2) * offset1 + offset2)
* Which this code does.
* mat1 and offset1 come from @child.
*/
graphene_matrix_transform_vec4 (mat1, offset2, &off2);
graphene_vec4_add (&off2, offset1, &off2);
graphene_matrix_transform_vec4 (matrix2, offset1, &offset);
graphene_vec4_add (&offset, offset2, &offset);
graphene_matrix_multiply (mat1, &mat2, &mat2);
graphene_matrix_multiply (matrix1, matrix2, &matrix);
result = gsk_color_matrix_node_new (gsk_color_matrix_node_get_child (child),
&mat2, &off2);
&matrix, &offset);
return result;
}