From 18305cbd98e02ab139beef769cbc90a2121bd1f5 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 11 Feb 2010 15:33:01 +0000 Subject: [PATCH] cogl_rectangle: avoid redundant copy of geometry All the cogl_rectangle* APIs normalize their input into into an array of _CoglMutiTexturedRect rectangles and pass these on to our work horse; _cogl_rectangles_with_multitexture_coords. The definition of _CoglMutiTexturedRect had 4 separate float members, x_1, y_1, x_2 and y_2 which meant for some common cases we were having to copy out from an array into these members. We are now able to simply point into the users array avoiding a copy which seems desirable when submiting lots of rectangles. --- clutter/cogl/cogl/cogl-journal-private.h | 5 +- clutter/cogl/cogl/cogl-journal.c | 31 ++++--- clutter/cogl/cogl/cogl-primitives.c | 135 ++++++++++++++++--------------- 3 files changed, 91 insertions(+), 80 deletions(-) diff --git a/clutter/cogl/cogl/cogl-journal-private.h b/clutter/cogl/cogl/cogl-journal-private.h index bc5f835..1d3eb1a 100644 --- a/clutter/cogl/cogl/cogl-journal-private.h +++ b/clutter/cogl/cogl/cogl-journal-private.h @@ -41,10 +41,7 @@ typedef struct _CoglJournalEntry } CoglJournalEntry; void -_cogl_journal_log_quad (float x_1, - float y_1, - float x_2, - float y_2, +_cogl_journal_log_quad (const float *position, CoglHandle material, int n_layers, guint32 fallback_layers, diff --git a/clutter/cogl/cogl/cogl-journal.c b/clutter/cogl/cogl/cogl-journal.c index 84846c8..9e58a1a 100644 --- a/clutter/cogl/cogl/cogl-journal.c +++ b/clutter/cogl/cogl/cogl-journal.c @@ -657,10 +657,7 @@ _cogl_journal_init (void) } void -_cogl_journal_log_quad (float x_1, - float y_1, - float x_2, - float y_2, +_cogl_journal_log_quad (const float *position, CoglHandle material, int n_layers, guint32 fallback_layers, @@ -722,15 +719,20 @@ _cogl_journal_log_quad (float x_1, memcpy (c, src_c, 4); } +#define X0 0 +#define Y0 1 +#define X1 2 +#define Y1 3 + if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM)) { - v[0] = x_1; v[1] = y_1; + v[0] = position[X0]; v[1] = position[Y0]; v += stride; - v[0] = x_1; v[1] = y_2; + v[0] = position[X0]; v[1] = position[Y1]; v += stride; - v[0] = x_2; v[1] = y_2; + v[0] = position[X1]; v[1] = position[Y1]; v += stride; - v[0] = x_2; v[1] = y_1; + v[0] = position[X1]; v[1] = position[Y0]; } else { @@ -739,23 +741,28 @@ _cogl_journal_log_quad (float x_1, cogl_get_modelview_matrix (&mv); - x = x_1, y = y_1, z = 0; w = 1; + x = position[X0], y = position[Y0], z = 0; w = 1; cogl_matrix_transform_point (&mv, &x, &y, &z, &w); v[0] = x; v[1] = y; v[2] = z; v += stride; - x = x_1, y = y_2, z = 0; w = 1; + x = position[X0], y = position[Y1], z = 0; w = 1; cogl_matrix_transform_point (&mv, &x, &y, &z, &w); v[0] = x; v[1] = y; v[2] = z; v += stride; - x = x_2, y = y_2, z = 0; w = 1; + x = position[X1], y = position[Y1], z = 0; w = 1; cogl_matrix_transform_point (&mv, &x, &y, &z, &w); v[0] = x; v[1] = y; v[2] = z; v += stride; - x = x_2, y = y_1, z = 0; w = 1; + x = position[X1], y = position[Y0], z = 0; w = 1; cogl_matrix_transform_point (&mv, &x, &y, &z, &w); v[0] = x; v[1] = y; v[2] = z; } +#undef X0 +#undef Y0 +#undef X1 +#undef Y1 + for (i = 0; i < n_layers; i++) { /* XXX: See definition of GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details diff --git a/clutter/cogl/cogl/cogl-primitives.c b/clutter/cogl/cogl/cogl-primitives.c index 9d94eef..486bc36 100644 --- a/clutter/cogl/cogl/cogl-primitives.c +++ b/clutter/cogl/cogl/cogl-primitives.c @@ -112,10 +112,7 @@ log_quad_sub_textures_cb (CoglHandle texture_handle, /* FIXME: when the wrap mode becomes part of the material we need to * be able to override the wrap mode when logging a quad. */ - _cogl_journal_log_quad (quad_coords[0], - quad_coords[1], - quad_coords[2], - quad_coords[3], + _cogl_journal_log_quad (quad_coords, state->material, 1, /* one layer */ 0, /* don't need to use fallbacks */ @@ -141,10 +138,7 @@ log_quad_sub_textures_cb (CoglHandle texture_handle, static void _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle, CoglHandle material, - float x_1, - float y_1, - float x_2, - float y_2, + const float *position, float tx_1, float ty_1, float tx_2, @@ -175,15 +169,20 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle, * inversions when we emit the final geometry. */ +#define X0 0 +#define Y0 1 +#define X1 2 +#define Y1 3 + tex_virtual_flipped_x = (tx_1 > tx_2) ? TRUE : FALSE; tex_virtual_flipped_y = (ty_1 > ty_2) ? TRUE : FALSE; state.tex_virtual_origin_x = tex_virtual_flipped_x ? tx_2 : tx_1; state.tex_virtual_origin_y = tex_virtual_flipped_y ? ty_2 : ty_1; - quad_flipped_x = (x_1 > x_2) ? TRUE : FALSE; - quad_flipped_y = (y_1 > y_2) ? TRUE : FALSE; - state.quad_origin_x = quad_flipped_x ? x_2 : x_1; - state.quad_origin_y = quad_flipped_y ? y_2 : y_1; + quad_flipped_x = (position[X0] > position[X1]) ? TRUE : FALSE; + quad_flipped_y = (position[Y0] > position[Y1]) ? TRUE : FALSE; + state.quad_origin_x = quad_flipped_x ? position[X1] : position[X0]; + state.quad_origin_y = quad_flipped_y ? position[Y1] : position[Y0]; /* flatten the two forms of coordinate inversion into one... */ state.flipped_x = tex_virtual_flipped_x ^ quad_flipped_x; @@ -192,8 +191,13 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle, /* We use the _len_AXIS naming here instead of _width and _height because * log_quad_slice_cb uses a macro with symbol concatenation to handle both * axis, so this is more convenient... */ - state.quad_len_x = fabs (x_2 - x_1); - state.quad_len_y = fabs (y_2 - y_1); + state.quad_len_x = fabs (position[X1] - position[X0]); + state.quad_len_y = fabs (position[Y1] - position[Y0]); + +#undef X0 +#undef Y0 +#undef X1 +#undef Y1 state.v_to_q_scale_x = fabs (state.quad_len_x / (tx_2 - tx_1)); state.v_to_q_scale_y = fabs (state.quad_len_y / (ty_2 - ty_1)); @@ -221,10 +225,7 @@ _cogl_texture_quad_multiple_primitives (CoglHandle tex_handle, * require repeating. */ static gboolean -_cogl_multitexture_quad_single_primitive (float x_1, - float y_1, - float x_2, - float y_2, +_cogl_multitexture_quad_single_primitive (const float *position, CoglHandle material, guint32 fallback_layers, const float *user_tex_coords, @@ -343,10 +344,7 @@ _cogl_multitexture_quad_single_primitive (float x_1, _cogl_texture_set_wrap_mode_parameter (tex_handle, wrap_mode); } - _cogl_journal_log_quad (x_1, - y_1, - x_2, - y_2, + _cogl_journal_log_quad (position, material, n_layers, fallback_layers, @@ -359,12 +357,9 @@ _cogl_multitexture_quad_single_primitive (float x_1, struct _CoglMutiTexturedRect { - float x_1; - float y_1; - float x_2; - float y_2; - const float *tex_coords; - int tex_coords_len; + const float *position; /* x0,y0,x1,y1 */ + const float *tex_coords; /* (tx0,ty0,tx1,ty1)(tx0,ty0,tx1,ty1)(... */ + int tex_coords_len; /* number of floats in tex_coords? */ }; static void @@ -495,10 +490,7 @@ _cogl_rectangles_with_multitexture_coords ( if (!all_use_sliced_quad_fallback) { gboolean success = - _cogl_multitexture_quad_single_primitive (rects[i].x_1, - rects[i].y_1, - rects[i].x_2, - rects[i].y_2, + _cogl_multitexture_quad_single_primitive (rects[i].position, material, fallback_layers, rects[i].tex_coords, @@ -525,8 +517,7 @@ _cogl_rectangles_with_multitexture_coords ( _cogl_texture_quad_multiple_primitives (tex_handle, material, - rects[i].x_1, rects[i].y_1, - rects[i].x_2, rects[i].y_2, + rects[i].position, tex_coords[0], tex_coords[1], tex_coords[2], @@ -547,14 +538,16 @@ cogl_rectangles (const float *verts, struct _CoglMutiTexturedRect *rects; int i; + /* XXX: All the cogl_rectangle* APIs normalize their input into an array of + * _CoglMutiTexturedRect rectangles and pass these on to our work horse; + * _cogl_rectangles_with_multitexture_coords. + */ + rects = g_alloca (n_rects * sizeof (struct _CoglMutiTexturedRect)); for (i = 0; i < n_rects; i++) { - rects[i].x_1 = verts[i * 4]; - rects[i].y_1 = verts[i * 4 + 1]; - rects[i].x_2 = verts[i * 4 + 2]; - rects[i].y_2 = verts[i * 4 + 3]; + rects[i].position = &verts[i * 4]; rects[i].tex_coords = NULL; rects[i].tex_coords_len = 0; } @@ -569,17 +562,16 @@ cogl_rectangles_with_texture_coords (const float *verts, struct _CoglMutiTexturedRect *rects; int i; + /* XXX: All the cogl_rectangle* APIs normalize their input into an array of + * _CoglMutiTexturedRect rectangles and pass these on to our work horse; + * _cogl_rectangles_with_multitexture_coords. + */ + rects = g_alloca (n_rects * sizeof (struct _CoglMutiTexturedRect)); for (i = 0; i < n_rects; i++) { - rects[i].x_1 = verts[i * 8]; - rects[i].y_1 = verts[i * 8 + 1]; - rects[i].x_2 = verts[i * 8 + 2]; - rects[i].y_2 = verts[i * 8 + 3]; - /* FIXME: rect should be defined to have a const float *geom; - * instead, to avoid this copy - * rect[i].geom = &verts[n_rects * 8]; */ + rects[i].position = &verts[i * 8]; rects[i].tex_coords = &verts[i * 8 + 4]; rects[i].tex_coords_len = 4; } @@ -597,18 +589,20 @@ cogl_rectangle_with_texture_coords (float x_1, float tx_2, float ty_2) { - float verts[8]; - - verts[0] = x_1; - verts[1] = y_1; - verts[2] = x_2; - verts[3] = y_2; - verts[4] = tx_1; - verts[5] = ty_1; - verts[6] = tx_2; - verts[7] = ty_2; - - cogl_rectangles_with_texture_coords (verts, 1); + const float position[4] = {x_1, y_1, x_2, y_2}; + const float tex_coords[4] = {tx_1, ty_1, tx_2, ty_2}; + struct _CoglMutiTexturedRect rect; + + /* XXX: All the cogl_rectangle* APIs normalize their input into an array of + * _CoglMutiTexturedRect rectangles and pass these on to our work horse; + * _cogl_rectangles_with_multitexture_coords. + */ + + rect.position = position; + rect.tex_coords = tex_coords; + rect.tex_coords_len = 4; + + _cogl_rectangles_with_multitexture_coords (&rect, 1); } void @@ -619,12 +613,15 @@ cogl_rectangle_with_multitexture_coords (float x_1, const float *user_tex_coords, int user_tex_coords_len) { + const float position[4] = {x_1, y_1, x_2, y_2}; struct _CoglMutiTexturedRect rect; - rect.x_1 = x_1; - rect.y_1 = y_1; - rect.x_2 = x_2; - rect.y_2 = y_2; + /* XXX: All the cogl_rectangle* APIs normalize their input into an array of + * _CoglMutiTexturedRect rectangles and pass these on to our work horse; + * _cogl_rectangles_with_multitexture_coords. + */ + + rect.position = position; rect.tex_coords = user_tex_coords; rect.tex_coords_len = user_tex_coords_len; @@ -637,9 +634,19 @@ cogl_rectangle (float x_1, float x_2, float y_2) { - cogl_rectangle_with_multitexture_coords (x_1, y_1, - x_2, y_2, - NULL, 0); + const float position[4] = {x_1, y_1, x_2, y_2}; + struct _CoglMutiTexturedRect rect; + + /* XXX: All the cogl_rectangle* APIs normalize their input into an array of + * _CoglMutiTexturedRect rectangles and pass these on to our work horse; + * _cogl_rectangles_with_multitexture_coords. + */ + + rect.position = position; + rect.tex_coords = NULL; + rect.tex_coords_len = 0; + + _cogl_rectangles_with_multitexture_coords (&rect, 1); } void -- 2.7.4