cogl: Don't flush the journal when flushing clip state
Flushing the clip state no longer does anything that would cause the journal to flush. The clip state is only flushed when flushing the framebuffer state and in all cases this ends up flushing the journal in one way or another anyway. Avoiding flushing the journal will make it easier to log the clip state in the journal. Previously when trying to set up a rectangle clip that can't be scissored or when using a path clip the code would use cogl_rectangle as part of the process to fill the stencil buffer. This is now changed to use a new internal _cogl_rectangle_immediate function which directly uses the vertex array API to draw a triangle strip without affecting the journal. This should be just as efficient as the previous journalled code because these places would end up flushing the journal immediately before and after submitting the single rectangle anyway and flushing the journal always creates a new vbo so it would effectively do the same thing. Similarly there is also a new internal _cogl_clear function that does not flush the journal.
This commit is contained in:
parent
db86a5a486
commit
caa991d7a1
@ -175,6 +175,7 @@ cogl_sources_c = \
|
||||
$(cogl_driver_sources) \
|
||||
$(cogl_winsys_common_sources) \
|
||||
$(cogl_tesselator_sources) \
|
||||
$(srcdir)/cogl-private.h \
|
||||
$(srcdir)/cogl-debug.h \
|
||||
$(srcdir)/cogl-debug-options.h \
|
||||
$(srcdir)/cogl-handle.h \
|
||||
@ -190,6 +191,7 @@ cogl_sources_c = \
|
||||
$(srcdir)/cogl-bitmap-private.h \
|
||||
$(srcdir)/cogl-bitmap.c \
|
||||
$(srcdir)/cogl-bitmap-fallback.c \
|
||||
$(srcdir)/cogl-primitives-private.h \
|
||||
$(srcdir)/cogl-primitives.h \
|
||||
$(srcdir)/cogl-primitives.c \
|
||||
$(srcdir)/cogl-path-private.h \
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "cogl-util.h"
|
||||
#include "cogl-path-private.h"
|
||||
#include "cogl-matrix-private.h"
|
||||
#include "cogl-primitives-private.h"
|
||||
|
||||
typedef struct _CoglClipStackRect CoglClipStackRect;
|
||||
typedef struct _CoglClipStackWindowRect CoglClipStackWindowRect;
|
||||
@ -283,15 +284,13 @@ add_stencil_clip_rectangle (float x_1,
|
||||
gboolean first)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
|
||||
CoglMatrixStack *modelview_stack =
|
||||
_cogl_framebuffer_get_modelview_stack (framebuffer);
|
||||
CoglMatrixStack *projection_stack =
|
||||
_cogl_framebuffer_get_projection_stack (framebuffer);
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* We don't log changes to the stencil buffer so need to flush any
|
||||
* batched geometry before we start... */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
_cogl_framebuffer_flush_state (framebuffer, 0);
|
||||
|
||||
/* temporarily swap in our special stenciling pipeline */
|
||||
cogl_push_source (ctx->stencil_pipeline);
|
||||
|
||||
@ -307,24 +306,23 @@ add_stencil_clip_rectangle (float x_1,
|
||||
GE( glStencilFunc (GL_NEVER, 0x1, 0x1) );
|
||||
GE( glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) );
|
||||
|
||||
cogl_rectangle (x_1, y_1, x_2, y_2);
|
||||
/* This can be called from the journal code which doesn't flush
|
||||
the matrix stacks between calls so we need to ensure they're
|
||||
flushed now */
|
||||
_cogl_matrix_stack_flush_to_gl (modelview_stack,
|
||||
COGL_MATRIX_MODELVIEW);
|
||||
_cogl_matrix_stack_flush_to_gl (projection_stack,
|
||||
COGL_MATRIX_PROJECTION);
|
||||
|
||||
_cogl_rectangle_immediate (x_1, y_1, x_2, y_2);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoglMatrixStack *modelview_stack =
|
||||
_cogl_framebuffer_get_modelview_stack (framebuffer);
|
||||
CoglMatrixStack *projection_stack =
|
||||
_cogl_framebuffer_get_projection_stack (framebuffer);
|
||||
|
||||
/* Add one to every pixel of the stencil buffer in the
|
||||
rectangle */
|
||||
GE( glStencilFunc (GL_NEVER, 0x1, 0x3) );
|
||||
GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) );
|
||||
cogl_rectangle (x_1, y_1, x_2, y_2);
|
||||
|
||||
/* make sure our rectangle hits the stencil buffer before we
|
||||
* change the stencil operation */
|
||||
_cogl_journal_flush ();
|
||||
_cogl_rectangle_immediate (x_1, y_1, x_2, y_2);
|
||||
|
||||
/* Subtract one from all pixels in the stencil buffer so that
|
||||
only pixels where both the original stencil buffer and the
|
||||
@ -337,16 +335,17 @@ add_stencil_clip_rectangle (float x_1,
|
||||
_cogl_matrix_stack_push (modelview_stack);
|
||||
_cogl_matrix_stack_load_identity (modelview_stack);
|
||||
|
||||
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
|
||||
_cogl_matrix_stack_flush_to_gl (modelview_stack,
|
||||
COGL_MATRIX_MODELVIEW);
|
||||
_cogl_matrix_stack_flush_to_gl (projection_stack,
|
||||
COGL_MATRIX_PROJECTION);
|
||||
|
||||
_cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
|
||||
|
||||
_cogl_matrix_stack_pop (modelview_stack);
|
||||
_cogl_matrix_stack_pop (projection_stack);
|
||||
}
|
||||
|
||||
/* make sure our rectangles hit the stencil buffer before we restore
|
||||
* the stencil function / operation */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
/* Restore the stencil mode */
|
||||
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
|
||||
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
|
||||
@ -610,10 +609,6 @@ _cogl_clip_stack_flush (CoglClipStack *stack)
|
||||
ctx->current_clip_stack_valid = TRUE;
|
||||
ctx->current_clip_stack = _cogl_clip_stack_ref (stack);
|
||||
|
||||
/* The current primitive journal does not support tracking changes to the
|
||||
* clip stack... */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
modelview_stack =
|
||||
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
|
||||
|
||||
|
@ -239,6 +239,11 @@ cogl_clip_ensure (void)
|
||||
CoglClipState *clip_state;
|
||||
|
||||
clip_state = _cogl_framebuffer_get_clip_state (_cogl_get_framebuffer ());
|
||||
/* Flushing the clip state doesn't cause the journal to be
|
||||
flushed. This function may be being called by an external
|
||||
application however so it makes sense to flush the journal
|
||||
here */
|
||||
_cogl_journal_flush ();
|
||||
_cogl_clip_state_flush (clip_state);
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,10 @@
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-path-private.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-primitives-private.h"
|
||||
#include "cogl-path.h"
|
||||
#include "cogl-private.h"
|
||||
#include "cogl-vertex-attribute-private.h"
|
||||
#include "tesselator/tesselator.h"
|
||||
|
||||
#include <string.h>
|
||||
@ -276,18 +280,16 @@ _cogl_path_fill_nodes_with_stencil_buffer (CoglPath *path)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
_cogl_journal_flush ();
|
||||
|
||||
g_assert (ctx->current_clip_stack_valid);
|
||||
|
||||
_cogl_add_path_to_stencil_buffer (path,
|
||||
ctx->current_clip_stack_uses_stencil,
|
||||
FALSE);
|
||||
|
||||
cogl_rectangle (path->data->path_nodes_min.x,
|
||||
path->data->path_nodes_min.y,
|
||||
path->data->path_nodes_max.x,
|
||||
path->data->path_nodes_max.y);
|
||||
_cogl_rectangle_immediate (path->data->path_nodes_min.x,
|
||||
path->data->path_nodes_min.y,
|
||||
path->data->path_nodes_max.x,
|
||||
path->data->path_nodes_max.y);
|
||||
|
||||
/* The stencil buffer now contains garbage so the clip area needs to
|
||||
* be rebuilt.
|
||||
@ -297,7 +299,6 @@ _cogl_path_fill_nodes_with_stencil_buffer (CoglPath *path)
|
||||
* only called when the journal first gets something logged in it; so
|
||||
* we call cogl_flush() to emtpy the journal.
|
||||
*/
|
||||
cogl_flush ();
|
||||
_cogl_clip_stack_dirty ();
|
||||
}
|
||||
|
||||
@ -342,11 +343,11 @@ _cogl_path_fill_nodes (CoglPath *path)
|
||||
|
||||
_cogl_path_build_vbo (path);
|
||||
|
||||
cogl_draw_indexed_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLES,
|
||||
0, /* first_vertex */
|
||||
path->data->vbo_n_indices,
|
||||
path->data->vbo_indices,
|
||||
path->data->vbo_attributes);
|
||||
_cogl_draw_indexed_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLES,
|
||||
0, /* first_vertex */
|
||||
path->data->vbo_n_indices,
|
||||
path->data->vbo_indices,
|
||||
path->data->vbo_attributes);
|
||||
}
|
||||
|
||||
void
|
||||
@ -364,14 +365,13 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* We don't track changes to the stencil buffer in the journal
|
||||
* so we need to flush any batched geometry first */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
|
||||
* as the pipeline state) when flushing the clip stack, so should
|
||||
* always be done first when preparing to draw. */
|
||||
_cogl_framebuffer_flush_state (framebuffer, 0);
|
||||
/* This can be called from the clip stack code which doesn't flush
|
||||
the matrix stacks between calls so we need to ensure they're
|
||||
flushed now */
|
||||
_cogl_matrix_stack_flush_to_gl (modelview_stack,
|
||||
COGL_MATRIX_MODELVIEW);
|
||||
_cogl_matrix_stack_flush_to_gl (projection_stack,
|
||||
COGL_MATRIX_PROJECTION);
|
||||
|
||||
/* Just setup a simple pipeline that doesn't use texturing... */
|
||||
cogl_push_source (ctx->stencil_pipeline);
|
||||
@ -399,24 +399,20 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
||||
/* If this is being called from the clip stack code then it
|
||||
will have set up a scissor for the minimum bounding box of
|
||||
all of the clips. That box will likely mean that this
|
||||
cogl_clear won't need to clear the entire buffer */
|
||||
cogl_clear (NULL, COGL_BUFFER_BIT_STENCIL);
|
||||
_cogl_clear won't need to clear the entire
|
||||
buffer. _cogl_clear is used instead of cogl_clear because
|
||||
it won't try to flush the journal */
|
||||
_cogl_clear (NULL, COGL_BUFFER_BIT_STENCIL);
|
||||
else
|
||||
{
|
||||
/* Just clear the bounding box */
|
||||
GE( glStencilMask (~(GLuint) 0) );
|
||||
GE( glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) );
|
||||
cogl_rectangle (data->path_nodes_min.x,
|
||||
data->path_nodes_min.y,
|
||||
data->path_nodes_max.x,
|
||||
data->path_nodes_max.y);
|
||||
/* Make sure the rectangle hits the stencil buffer before
|
||||
* directly changing other GL state. */
|
||||
_cogl_journal_flush ();
|
||||
/* NB: The journal flushing may trash the modelview state and
|
||||
* enable flags */
|
||||
_cogl_matrix_stack_flush_to_gl (modelview_stack,
|
||||
COGL_MATRIX_MODELVIEW);
|
||||
_cogl_rectangle_immediate (data->path_nodes_min.x,
|
||||
data->path_nodes_min.y,
|
||||
data->path_nodes_max.x,
|
||||
data->path_nodes_max.y);
|
||||
/* NB: The rectangle may trash the enable flags */
|
||||
_cogl_enable (enable_flags);
|
||||
}
|
||||
GE (glStencilMask (1));
|
||||
@ -448,11 +444,8 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
||||
_cogl_matrix_stack_flush_to_gl (modelview_stack,
|
||||
COGL_MATRIX_MODELVIEW);
|
||||
|
||||
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
|
||||
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
|
||||
/* Make sure these rectangles hit the stencil buffer before we
|
||||
* restore the stencil op/func. */
|
||||
_cogl_journal_flush ();
|
||||
_cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
|
||||
_cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
|
||||
|
||||
_cogl_matrix_stack_pop (modelview_stack);
|
||||
_cogl_matrix_stack_pop (projection_stack);
|
||||
@ -489,6 +482,13 @@ cogl_path_fill_preserve (void)
|
||||
if (path->data->path_nodes->len == 0)
|
||||
return;
|
||||
|
||||
_cogl_journal_flush ();
|
||||
|
||||
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
|
||||
* as the pipeline state) when flushing the clip stack, so should
|
||||
* always be done first when preparing to draw. */
|
||||
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
|
||||
|
||||
_cogl_path_fill_nodes (path);
|
||||
}
|
||||
|
||||
|
43
cogl/cogl-primitives-private.h
Normal file
43
cogl/cogl-primitives-private.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COGL_PRIMITIVES_PRIVATE_H
|
||||
#define __COGL_PRIMITIVES_PRIVATE_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Draws a rectangle without going through the journal so that it will
|
||||
be flushed immediately. This should only be used in situations
|
||||
where the code may be called while the journal is already being
|
||||
flushed. In that case using the journal would go wrong */
|
||||
void
|
||||
_cogl_rectangle_immediate (float x_1,
|
||||
float y_1,
|
||||
float x_2,
|
||||
float y_2);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_PRIMITIVES_PRIVATE_H */
|
@ -819,6 +819,46 @@ cogl_rectangle (float x_1,
|
||||
_cogl_rectangles_with_multitexture_coords (&rect, 1);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_rectangle_immediate (float x_1,
|
||||
float y_1,
|
||||
float x_2,
|
||||
float y_2)
|
||||
{
|
||||
/* Draw a rectangle using the vertex array API to avoid going
|
||||
through the journal. This should only be used in cases where the
|
||||
code might be called while the journal is already being flushed
|
||||
such as when flushing the clip state */
|
||||
float vertices[8] =
|
||||
{
|
||||
x_1, y_1,
|
||||
x_1, y_2,
|
||||
x_2, y_1,
|
||||
x_2, y_2
|
||||
};
|
||||
CoglVertexArray *vertex_array;
|
||||
CoglVertexAttribute *attributes[2];
|
||||
|
||||
vertex_array = cogl_vertex_array_new (sizeof (vertices));
|
||||
cogl_buffer_set_data (COGL_BUFFER (vertex_array), 0,
|
||||
(guint8 *) vertices, sizeof (vertices));
|
||||
attributes[0] = cogl_vertex_attribute_new (vertex_array,
|
||||
"cogl_position_in",
|
||||
sizeof (float) * 2, /* stride */
|
||||
0, /* offset */
|
||||
2, /* n_components */
|
||||
COGL_VERTEX_ATTRIBUTE_TYPE_FLOAT);
|
||||
attributes[1] = NULL;
|
||||
|
||||
_cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLE_STRIP,
|
||||
0, /* first_index */
|
||||
4, /* n_vertices */
|
||||
attributes);
|
||||
|
||||
cogl_object_unref (attributes[0]);
|
||||
cogl_object_unref (vertex_array);
|
||||
}
|
||||
|
||||
typedef struct _AppendTexCoordsState
|
||||
{
|
||||
const CoglTextureVertex *vertices_in;
|
||||
|
34
cogl/cogl-private.h
Normal file
34
cogl/cogl-private.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COGL_PRIVATE_H__
|
||||
#define __COGL_PRIVATE_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void
|
||||
_cogl_clear (const CoglColor *color, unsigned long buffers);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_PRIVATE_H__ */
|
30
cogl/cogl.c
30
cogl/cogl.c
@ -148,20 +148,15 @@ cogl_check_extension (const char *name, const char *ext)
|
||||
return _cogl_check_extension (name, ext);
|
||||
}
|
||||
|
||||
/* This version of cogl_clear can be used internally as an alternative
|
||||
to avoid flushing the journal or the framebuffer state. This is
|
||||
needed when doing operations that may be called whiling flushing
|
||||
the journal */
|
||||
void
|
||||
cogl_clear (const CoglColor *color, unsigned long buffers)
|
||||
_cogl_clear (const CoglColor *color, unsigned long buffers)
|
||||
{
|
||||
GLbitfield gl_buffers = 0;
|
||||
|
||||
COGL_NOTE (DRAW, "Clear begin");
|
||||
|
||||
_cogl_journal_flush ();
|
||||
|
||||
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
|
||||
* as the pipeline state) when flushing the clip stack, so should
|
||||
* always be done first when preparing to draw. */
|
||||
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
|
||||
|
||||
if (buffers & COGL_BUFFER_BIT_COLOR)
|
||||
{
|
||||
GE( glClearColor (cogl_color_get_red_float (color),
|
||||
@ -201,6 +196,21 @@ cogl_clear (const CoglColor *color, unsigned long buffers)
|
||||
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
|
||||
ctxt->journal_rectangles_color = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cogl_clear (const CoglColor *color, unsigned long buffers)
|
||||
{
|
||||
COGL_NOTE (DRAW, "Clear begin");
|
||||
|
||||
_cogl_journal_flush ();
|
||||
|
||||
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
|
||||
* as the pipeline state) when flushing the clip stack, so should
|
||||
* always be done first when preparing to draw. */
|
||||
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
|
||||
|
||||
_cogl_clear (color, buffers);;
|
||||
|
||||
COGL_NOTE (DRAW, "Clear end");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user