forked from AuroraMiddleware/gtk
gl renderer: Expand matrix metadata extraction
Instead of getting the translation x/y everytime we use the modelview, get it once, when extracting the metadata. Do the same with the scale. And save if the matrix is "simple" at all, i.e. if it only consists of a translation and/or scale. This will be helpful later when we start drawing transformed nodes on textures.
This commit is contained in:
parent
5ea211bbb1
commit
12378f0afa
@ -7,7 +7,6 @@ ops_finish (RenderOpBuilder *builder)
|
|||||||
g_array_free (builder->mv_stack, TRUE);
|
g_array_free (builder->mv_stack, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
rgba_to_float (const GdkRGBA *c,
|
rgba_to_float (const GdkRGBA *c,
|
||||||
float *f)
|
float *f)
|
||||||
@ -28,38 +27,9 @@ ops_get_scale (const RenderOpBuilder *builder)
|
|||||||
|
|
||||||
head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
|
head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
|
||||||
|
|
||||||
return head->metadata.scale;
|
/* TODO: Use two separate values */
|
||||||
}
|
return MAX (head->metadata.scale_x,
|
||||||
|
head->metadata.scale_y);
|
||||||
static inline gboolean
|
|
||||||
matrix_is_only_translation (const graphene_matrix_t *mat)
|
|
||||||
{
|
|
||||||
graphene_vec4_t row1;
|
|
||||||
graphene_vec4_t row2;
|
|
||||||
graphene_vec4_t row3;
|
|
||||||
graphene_vec4_t row;
|
|
||||||
|
|
||||||
graphene_vec4_init (&row1, 1, 0, 0, 0);
|
|
||||||
graphene_vec4_init (&row2, 0, 1, 0, 0);
|
|
||||||
graphene_vec4_init (&row3, 0, 0, 1, 0);
|
|
||||||
|
|
||||||
graphene_matrix_get_row (mat, 0, &row);
|
|
||||||
if (!graphene_vec4_equal (&row1, &row))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
graphene_matrix_get_row (mat, 1, &row);
|
|
||||||
if (!graphene_vec4_equal (&row2, &row))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
graphene_matrix_get_row (mat, 2, &row);
|
|
||||||
if (!graphene_vec4_equal (&row3, &row))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
graphene_matrix_get_row (mat, 3, &row);
|
|
||||||
if (graphene_vec4_get_w (&row) != 1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -69,10 +39,9 @@ extract_matrix_metadata (const graphene_matrix_t *m,
|
|||||||
graphene_vec3_t col1;
|
graphene_vec3_t col1;
|
||||||
graphene_vec3_t col2;
|
graphene_vec3_t col2;
|
||||||
|
|
||||||
/* Is this matrix JUST a translation? */
|
/* Translate */
|
||||||
md->is_only_translation = matrix_is_only_translation (m);
|
md->translate_x = graphene_matrix_get_value (m, 3, 0);
|
||||||
|
md->translate_y = graphene_matrix_get_value (m, 3, 1);
|
||||||
/* TODO: We should probably split this up into two values... */
|
|
||||||
|
|
||||||
/* Scale */
|
/* Scale */
|
||||||
graphene_vec3_init (&col1,
|
graphene_vec3_init (&col1,
|
||||||
@ -85,9 +54,36 @@ extract_matrix_metadata (const graphene_matrix_t *m,
|
|||||||
graphene_matrix_get_value (m, 1, 1),
|
graphene_matrix_get_value (m, 1, 1),
|
||||||
graphene_matrix_get_value (m, 2, 1));
|
graphene_matrix_get_value (m, 2, 1));
|
||||||
|
|
||||||
md->scale = MAX (graphene_vec3_length (&col1),
|
md->scale_x = graphene_vec3_length (&col1);
|
||||||
graphene_vec3_length (&col2));
|
md->scale_y = graphene_vec3_length (&col2);
|
||||||
|
|
||||||
|
/* A simple matrix (in our case) is one that doesn't do anything but scale
|
||||||
|
* and/or translate.
|
||||||
|
*
|
||||||
|
* For orher matrices, we fall back to offscreen drawing.
|
||||||
|
*/
|
||||||
|
md->simple = TRUE;
|
||||||
|
{
|
||||||
|
static const guchar check_zero[4][4] = {
|
||||||
|
{ 0, 1, 0, 1 }, /* If any of the values marked as '1' here is non-zero, */
|
||||||
|
{ 1, 0, 0, 1 }, /* We have to resort to offscreen drawing later on. */
|
||||||
|
{ 1, 1, 0, 1 },
|
||||||
|
{ 0, 0, 0, 0 },
|
||||||
|
};
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
for (x = 0; x < 4; x ++)
|
||||||
|
for (y = 0; y < 4; y ++)
|
||||||
|
if (check_zero[y][x] &&
|
||||||
|
graphene_matrix_get_value (m, y, x) != 0.0f)
|
||||||
|
{
|
||||||
|
md->simple = FALSE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
md->only_translation = (md->simple && md->scale_x == 0 && md->scale_y == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -103,14 +99,12 @@ ops_transform_bounds_modelview (const RenderOpBuilder *builder,
|
|||||||
|
|
||||||
head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
|
head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
|
||||||
|
|
||||||
if (head->metadata.is_only_translation)
|
if (head->metadata.only_translation)
|
||||||
{
|
{
|
||||||
graphene_vec4_t row4;
|
|
||||||
|
|
||||||
/* TODO: We could do the get_row here only once, when setting the new modelview matrix. */
|
|
||||||
graphene_matrix_get_row (builder->current_modelview, 3, &row4);
|
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
graphene_rect_offset (dst, graphene_vec4_get_x (&row4), graphene_vec4_get_y (&row4));
|
graphene_rect_offset (dst,
|
||||||
|
head->metadata.translate_x,
|
||||||
|
head->metadata.translate_y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -16,8 +16,13 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
guint is_only_translation : 1;
|
float translate_x;
|
||||||
float scale;
|
float translate_y;
|
||||||
|
float scale_x;
|
||||||
|
float scale_y;
|
||||||
|
|
||||||
|
guint simple : 1;
|
||||||
|
guint only_translation : 1;
|
||||||
} OpsMatrixMetadata;
|
} OpsMatrixMetadata;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
Loading…
Reference in New Issue
Block a user