[cogl matrix stack] Create a client side matrix stack for the projection matrix
The cost of glGetFloatv with Mesa is still representing a majority of our
time in OpenGL for some applications, and the last thing left using this is
the current-matrix API when getting the projection matrix.
This adds a matrix stack for the projection matrix, so all getting, setting
and modification of the projection matrix is now managed by Cogl and it's only
when we come to draw that we flush changes to the matrix to OpenGL.
This also brings us closer to being able to drop internal use of the
deprecated OpenGL matrix functions, re: commit 54159f5a1d
This commit is contained in:
parent
fcc3d56209
commit
fffcf579d5
@ -22,6 +22,7 @@
|
||||
*
|
||||
* Authors:
|
||||
* Havoc Pennington <hp@pobox.com> for litl
|
||||
* Robert Bragg <robert@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -53,16 +54,43 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
static void
|
||||
_cogl_get_client_stack (CoglContext *ctx,
|
||||
CoglMatrixMode mode,
|
||||
CoglMatrixStack **current_stack_p)
|
||||
{
|
||||
if (ctx->modelview_stack &&
|
||||
mode == COGL_MATRIX_MODELVIEW)
|
||||
*current_stack_p = ctx->modelview_stack;
|
||||
else if (ctx->projection_stack &&
|
||||
mode == COGL_MATRIX_PROJECTION)
|
||||
*current_stack_p = ctx->projection_stack;
|
||||
else
|
||||
*current_stack_p = NULL;
|
||||
}
|
||||
|
||||
#define _COGL_GET_CONTEXT_AND_STACK(contextvar, stackvar, rval) \
|
||||
CoglMatrixStack *stackvar; \
|
||||
_COGL_GET_CONTEXT (contextvar, rval); \
|
||||
_cogl_get_client_stack (contextvar, ctx->matrix_mode, &stackvar)
|
||||
|
||||
void
|
||||
_cogl_set_current_matrix (CoglMatrixMode mode)
|
||||
{
|
||||
GLenum gl_mode;
|
||||
CoglMatrixStack *current_stack; \
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (mode == ctx->matrix_mode)
|
||||
return;
|
||||
ctx->matrix_mode = mode;
|
||||
|
||||
/* If we have a client side stack then then the GL matrix mode only needs
|
||||
* changing when we come to flush it to OpenGL */
|
||||
_cogl_get_client_stack (ctx, mode, ¤t_stack);
|
||||
if (current_stack)
|
||||
return;
|
||||
|
||||
gl_mode = 0; /* silence compiler warning */
|
||||
switch (mode)
|
||||
{
|
||||
@ -80,22 +108,6 @@ _cogl_set_current_matrix (CoglMatrixMode mode)
|
||||
GE (glMatrixMode (gl_mode));
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_get_client_stack (CoglContext *ctx,
|
||||
CoglMatrixStack **current_stack_p)
|
||||
{
|
||||
if (ctx->modelview_stack &&
|
||||
ctx->matrix_mode == COGL_MATRIX_MODELVIEW)
|
||||
*current_stack_p = ctx->modelview_stack;
|
||||
else
|
||||
*current_stack_p = NULL;
|
||||
}
|
||||
|
||||
#define _COGL_GET_CONTEXT_AND_STACK(contextvar, stackvar, rval) \
|
||||
CoglMatrixStack *stackvar; \
|
||||
_COGL_GET_CONTEXT (contextvar, rval); \
|
||||
_cogl_get_client_stack (contextvar, &stackvar)
|
||||
|
||||
void
|
||||
_cogl_current_matrix_push (void)
|
||||
{
|
||||
@ -204,7 +216,7 @@ _cogl_current_matrix_frustum (float left,
|
||||
if (current_stack != NULL)
|
||||
_cogl_matrix_stack_frustum (current_stack,
|
||||
left, right,
|
||||
top, bottom,
|
||||
bottom, top,
|
||||
near_val,
|
||||
far_val);
|
||||
else
|
||||
@ -269,13 +281,13 @@ void
|
||||
_cogl_get_matrix (CoglMatrixMode mode,
|
||||
CoglMatrix *matrix)
|
||||
{
|
||||
CoglMatrixStack *current_stack;
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (ctx->modelview_stack != NULL &&
|
||||
mode == COGL_MATRIX_MODELVIEW)
|
||||
{
|
||||
_cogl_matrix_stack_get (ctx->modelview_stack, matrix);
|
||||
}
|
||||
_cogl_get_client_stack (ctx, mode, ¤t_stack);
|
||||
|
||||
if (current_stack)
|
||||
_cogl_matrix_stack_get (current_stack, matrix);
|
||||
else
|
||||
{
|
||||
GLenum gl_mode;
|
||||
@ -319,24 +331,25 @@ _cogl_current_matrix_state_init (void)
|
||||
|
||||
ctx->matrix_mode = COGL_MATRIX_MODELVIEW;
|
||||
ctx->modelview_stack = NULL;
|
||||
ctx->projection_stack = NULL;
|
||||
|
||||
#if 0
|
||||
if (ctx->indirect ||
|
||||
cogl_debug_flags & COGL_DEBUG_FORCE_CLIENT_SIDE_MATRICES)
|
||||
#endif
|
||||
{
|
||||
ctx->modelview_stack =
|
||||
_cogl_matrix_stack_new ();
|
||||
ctx->modelview_stack = _cogl_matrix_stack_new ();
|
||||
ctx->projection_stack = _cogl_matrix_stack_new ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_current_matrix_state_destroy (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
|
||||
|
||||
if (ctx->modelview_stack)
|
||||
_cogl_matrix_stack_destroy (ctx->modelview_stack);
|
||||
if (current_stack)
|
||||
_cogl_matrix_stack_destroy (current_stack);
|
||||
}
|
||||
|
||||
void
|
||||
@ -344,32 +357,35 @@ _cogl_current_matrix_state_flush (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (ctx->matrix_mode != COGL_MATRIX_MODELVIEW)
|
||||
if (ctx->matrix_mode != COGL_MATRIX_MODELVIEW &&
|
||||
ctx->matrix_mode != COGL_MATRIX_PROJECTION)
|
||||
{
|
||||
g_warning ("matrix state must be flushed in MODELVIEW mode");
|
||||
g_warning ("matrix state must be flushed in "
|
||||
"MODELVIEW or PROJECTION mode");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->modelview_stack)
|
||||
if (ctx->modelview_stack &&
|
||||
ctx->matrix_mode == COGL_MATRIX_MODELVIEW)
|
||||
{
|
||||
_cogl_matrix_stack_flush_to_gl (ctx->modelview_stack,
|
||||
GL_MODELVIEW);
|
||||
}
|
||||
else if (ctx->projection_stack &&
|
||||
ctx->matrix_mode == COGL_MATRIX_PROJECTION)
|
||||
{
|
||||
_cogl_matrix_stack_flush_to_gl (ctx->projection_stack,
|
||||
GL_PROJECTION);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_current_matrix_state_dirty (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
|
||||
|
||||
if (ctx->matrix_mode != COGL_MATRIX_MODELVIEW)
|
||||
{
|
||||
g_warning ("matrix state must be dirtied in MODELVIEW mode");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->modelview_stack)
|
||||
_cogl_matrix_stack_dirty (ctx->modelview_stack);
|
||||
if (current_stack)
|
||||
_cogl_matrix_stack_dirty (current_stack);
|
||||
}
|
||||
|
||||
void
|
||||
@ -445,8 +461,6 @@ cogl_frustum (float left,
|
||||
z_near,
|
||||
z_far);
|
||||
|
||||
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
|
||||
|
||||
/* Calculate and store the inverse of the matrix */
|
||||
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
|
||||
|
||||
@ -524,3 +538,12 @@ cogl_set_projection_matrix (CoglMatrix *matrix)
|
||||
_cogl_current_matrix_load (matrix);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_flush_matrix_stacks (void)
|
||||
{
|
||||
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
|
||||
_cogl_current_matrix_state_flush ();
|
||||
}
|
||||
|
||||
|
@ -90,4 +90,6 @@ void _cogl_current_matrix_state_destroy (void);
|
||||
void _cogl_current_matrix_state_flush (void);
|
||||
void _cogl_current_matrix_state_dirty (void);
|
||||
|
||||
void _cogl_flush_matrix_stacks (void);
|
||||
|
||||
#endif /* __COGL_CURRENT_MATRIX_H */
|
||||
|
@ -344,10 +344,7 @@ _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack,
|
||||
if (stack->flushed_state == state)
|
||||
return;
|
||||
|
||||
/* NOTE we assume caller was in MODELVIEW mode */
|
||||
|
||||
if (gl_mode != GL_MODELVIEW)
|
||||
GE (glMatrixMode (gl_mode));
|
||||
GE (glMatrixMode (gl_mode));
|
||||
|
||||
/* In theory it might help the GL implementation if we used our
|
||||
* local analysis of the matrix and called Translate/Scale rather
|
||||
@ -356,9 +353,6 @@ _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack,
|
||||
|
||||
GE (glLoadMatrixf (cogl_matrix_get_array (&state->matrix)));
|
||||
stack->flushed_state = state;
|
||||
|
||||
if (gl_mode != GL_MODELVIEW)
|
||||
GE (glMatrixMode (GL_MODELVIEW));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -24,6 +24,7 @@
|
||||
* Robert Bragg <robert@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <cogl.h>
|
||||
#include <cogl-matrix.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -546,9 +546,13 @@ _cogl_journal_flush (void)
|
||||
state.vbo_offset = (char *)ctx->logged_vertices->data;
|
||||
|
||||
/* Since the journal deals with emitting the modelview matrices manually
|
||||
* we need to dirty our client side matrix stack cache... */
|
||||
* we need to dirty our client side modelview matrix stack cache... */
|
||||
_cogl_current_matrix_state_dirty ();
|
||||
|
||||
/* And explicitly flush other matrix stacks... */
|
||||
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
|
||||
_cogl_current_matrix_state_flush ();
|
||||
|
||||
/* If we have transformed all our quads at log time then the whole journal
|
||||
* then we ensure no further model transform is applied by loading the
|
||||
* identity matrix here...*/
|
||||
@ -1460,7 +1464,7 @@ _cogl_texture_sliced_polygon (CoglTextureVertex *vertices,
|
||||
options.layer0_override_texture = gl_handle;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
|
||||
GE( glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices) );
|
||||
}
|
||||
@ -1564,7 +1568,7 @@ _cogl_multitexture_unsliced_polygon (CoglTextureVertex *vertices,
|
||||
options.flags |= COGL_MATERIAL_FLUSH_SKIP_GL_COLOR;
|
||||
options.fallback_layers = fallback_layers;
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
|
||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
|
||||
}
|
||||
|
@ -1751,7 +1751,7 @@ cogl_vertex_buffer_draw (CoglHandle handle,
|
||||
buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
|
||||
|
||||
cogl_clip_ensure ();
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
enable_state_for_drawing_buffer (buffer);
|
||||
|
||||
/* FIXME: flush cogl cache */
|
||||
@ -1888,7 +1888,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
|
||||
indices = _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle);
|
||||
|
||||
cogl_clip_ensure ();
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
enable_state_for_drawing_buffer (buffer);
|
||||
|
||||
byte_offset = indices_offset * get_indices_type_size (indices->type);
|
||||
|
@ -324,7 +324,7 @@ set_clip_plane (GLint plane_num,
|
||||
_cogl_current_matrix_rotate (angle, 0.0f, 0.0f, 1.0f);
|
||||
_cogl_current_matrix_translate (-vertex_a[0], -vertex_a[1], -vertex_a[2]);
|
||||
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
|
||||
plane[0] = 0;
|
||||
plane[1] = -1.0;
|
||||
@ -568,6 +568,7 @@ _cogl_setup_viewport (guint width,
|
||||
cogl_get_projection_matrix (&projection_matrix);
|
||||
z_camera = 0.5 * projection_matrix.xx;
|
||||
|
||||
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
|
||||
_cogl_current_matrix_identity ();
|
||||
_cogl_current_matrix_translate (-0.5f, -0.5f, -z_camera);
|
||||
_cogl_current_matrix_scale (1.0f / width, -1.0f / height, 1.0f / width);
|
||||
@ -706,7 +707,7 @@ cogl_disable_fog (void)
|
||||
void
|
||||
cogl_flush_gl_state (int flags)
|
||||
{
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -800,7 +801,7 @@ cogl_begin_gl (void)
|
||||
cogl_clip_ensure ();
|
||||
|
||||
/* Flush any client side matrix state */
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
|
||||
|
||||
/* Setup the state for the current material */
|
||||
|
@ -60,6 +60,7 @@ typedef struct
|
||||
/* Client-side matrix stack or NULL if none */
|
||||
CoglMatrixMode matrix_mode;
|
||||
CoglMatrixStack *modelview_stack;
|
||||
CoglMatrixStack *projection_stack;
|
||||
|
||||
/* Cache of inverse projection matrix */
|
||||
float inverse_projection[16];
|
||||
|
@ -88,7 +88,7 @@ _cogl_path_stroke_nodes ()
|
||||
options.disable_layers = (guint32)~0;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
|
||||
while (path_start < ctx->path_nodes->len)
|
||||
{
|
||||
@ -177,7 +177,7 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
}
|
||||
ctx->n_texcoord_arrays_enabled = 0;
|
||||
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
|
||||
while (path_start < path_size)
|
||||
{
|
||||
@ -226,7 +226,7 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
_cogl_current_matrix_push ();
|
||||
_cogl_current_matrix_identity ();
|
||||
|
||||
_cogl_current_matrix_state_flush ();
|
||||
_cogl_flush_matrix_stacks ();
|
||||
|
||||
glRectf (-1.0, -1.0, 1.0, 1.0);
|
||||
glRectf (-1.0, -1.0, 1.0, 1.0);
|
||||
|
Loading…
Reference in New Issue
Block a user