[cogl-primitives] Don't clear the whole stencil buffer

When _cogl_add_path_to_stencil_buffer is used to draw a path we don't
need to clear the entire stencil buffer. Instead it can clear just the
bounding box of the path. This adds an extra parameter called
'need_clear' which is only set if the stencil buffer is being used for
clipping.

http://bugzilla.openedhand.com/show_bug.cgi?id=1829
This commit is contained in:
Neil Roberts 2009-10-05 13:37:11 +01:00
parent bc8faf52f4
commit dab1da20ae
2 changed files with 34 additions and 9 deletions

View File

@ -41,7 +41,8 @@ void _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
floatVec2 nodes_max,
guint path_size,
CoglPathNode *path,
gboolean merge);
gboolean merge,
gboolean need_clear);
typedef struct _CoglClipStack CoglClipStack;
@ -696,7 +697,8 @@ _cogl_flush_clip_state (CoglClipStackState *clip_state)
path->path_nodes_max,
path->path_size,
path->path,
using_stencil_buffer);
using_stencil_buffer,
TRUE);
_cogl_matrix_stack_pop (modelview_stack);

View File

@ -1109,7 +1109,8 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
floatVec2 nodes_max,
unsigned int path_size,
CoglPathNode *path,
gboolean merge)
gboolean merge,
gboolean need_clear)
{
unsigned int path_start = 0;
unsigned int sub_path_num = 0;
@ -1151,6 +1152,11 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
_cogl_path_get_bounds (nodes_min, nodes_max,
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
GE( glEnable (GL_STENCIL_TEST) );
GE( glColorMask (FALSE, FALSE, FALSE, FALSE) );
GE( glDepthMask (FALSE) );
if (merge)
{
GE (glStencilMask (2));
@ -1158,17 +1164,33 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
}
else
{
cogl_clear (NULL, COGL_BUFFER_BIT_STENCIL);
/* If we're not using the stencil buffer for clipping then we
don't need to clear the whole stencil buffer, just the area
that will be drawn */
if (need_clear)
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 (bounds_x, bounds_y,
bounds_x + bounds_w, bounds_y + bounds_h);
/* 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_enable (enable_flags);
}
GE (glStencilMask (1));
GE (glStencilFunc (GL_LEQUAL, 0x1, 0x3));
}
GE (glEnable (GL_STENCIL_TEST));
GE (glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT));
GE (glColorMask (FALSE, FALSE, FALSE, FALSE));
GE (glDepthMask (FALSE));
for (i = 0; i < ctx->n_texcoord_arrays_enabled; i++)
{
GE (glClientActiveTexture (GL_TEXTURE0 + i));
@ -1468,7 +1490,8 @@ _cogl_path_fill_nodes (void)
ctx->path_nodes->len,
&g_array_index (ctx->path_nodes,
CoglPathNode, 0),
clip_state->stencil_used);
clip_state->stencil_used,
FALSE);
cogl_rectangle (bounds_x, bounds_y,
bounds_x + bounds_w, bounds_y + bounds_h);