[cogl/wip/rib/master-next: 8/36] clip-stack: Move path flushing code to cogl-clip-stack.c
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/rib/master-next: 8/36] clip-stack: Move path flushing code to cogl-clip-stack.c
- Date: Mon, 17 Oct 2011 12:45:56 +0000 (UTC)
commit fe4097f7f8a4bd7244afb86f79390b1324beb688
Author: Robert Bragg <robert linux intel com>
Date: Sat Oct 1 17:55:41 2011 +0100
clip-stack: Move path flushing code to cogl-clip-stack.c
The code that adds the silhouette of a path to the stencil buffer was
living in cogl2-path.c which seemed out of place when the bulk of the
work really related more to how the stencil buffer is managed and
basically only one line (a call to _cogl_path_fill_nodes) really related
to the path code directly.
This moves the code into cogl-clip-stack.c alone with similar code
that can add rectangle masks to the stencil buffer.
cogl/cogl-clip-stack.c | 116 ++++++++++++++++++++++++++++++++++++++++++++-
cogl/cogl-path-private.h | 3 +
cogl/cogl2-path.c | 111 +-------------------------------------------
3 files changed, 117 insertions(+), 113 deletions(-)
---
diff --git a/cogl/cogl-clip-stack.c b/cogl/cogl-clip-stack.c
index 004445a..c01a74c 100644
--- a/cogl/cogl-clip-stack.c
+++ b/cogl/cogl-clip-stack.c
@@ -42,6 +42,7 @@
#include "cogl-matrix-private.h"
#include "cogl-primitives-private.h"
#include "cogl-private.h"
+#include "cogl-pipeline-opengl-private.h"
#ifndef GL_CLIP_PLANE0
#define GL_CLIP_PLANE0 0x3000
@@ -273,6 +274,114 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
cogl_pop_source ();
}
+void
+add_stencil_clip_path (CoglFramebuffer *framebuffer,
+ CoglPath *path,
+ gboolean merge,
+ gboolean need_clear)
+{
+ CoglPathData *data = path->data;
+ CoglMatrixStack *modelview_stack =
+ _cogl_framebuffer_get_modelview_stack (framebuffer);
+ CoglMatrixStack *projection_stack =
+ _cogl_framebuffer_get_projection_stack (framebuffer);
+ CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
+
+ /* 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, FALSE);
+
+ _cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, FALSE, 0);
+
+ GE( ctx, glEnable (GL_STENCIL_TEST) );
+
+ GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) );
+ GE( ctx, glDepthMask (FALSE) );
+
+ if (merge)
+ {
+ GE (ctx, glStencilMask (2));
+ GE (ctx, glStencilFunc (GL_LEQUAL, 0x2, 0x6));
+ }
+ else
+ {
+ /* 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)
+ /* 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_framebuffer_clear_without_flush4f is used instead
+ of cogl_clear because it won't try to flush the journal */
+ _cogl_framebuffer_clear_without_flush4f (framebuffer,
+ COGL_BUFFER_BIT_STENCIL,
+ 0, 0, 0, 0);
+ else
+ {
+ /* Just clear the bounding box */
+ GE( ctx, glStencilMask (~(GLuint) 0) );
+ GE( ctx, glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) );
+ _cogl_rectangle_immediate (data->path_nodes_min.x,
+ data->path_nodes_min.y,
+ data->path_nodes_max.x,
+ data->path_nodes_max.y);
+ }
+ GE (ctx, glStencilMask (1));
+ GE (ctx, glStencilFunc (GL_LEQUAL, 0x1, 0x3));
+ }
+
+ GE (ctx, glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT));
+
+ if (path->data->path_nodes->len >= 3)
+ _cogl_path_fill_nodes (path);
+
+ if (merge)
+ {
+ /* Now we have the new stencil buffer in bit 1 and the old
+ stencil buffer in bit 0 so we need to intersect them */
+ GE (ctx, glStencilMask (3));
+ GE (ctx, glStencilFunc (GL_NEVER, 0x2, 0x3));
+ GE (ctx, glStencilOp (GL_DECR, GL_DECR, GL_DECR));
+ /* Decrement all of the bits twice so that only pixels where the
+ value is 3 will remain */
+
+ _cogl_matrix_stack_push (projection_stack);
+ _cogl_matrix_stack_load_identity (projection_stack);
+ _cogl_matrix_stack_flush_to_gl (projection_stack,
+ COGL_MATRIX_PROJECTION);
+
+ _cogl_matrix_stack_push (modelview_stack);
+ _cogl_matrix_stack_load_identity (modelview_stack);
+ _cogl_matrix_stack_flush_to_gl (modelview_stack,
+ COGL_MATRIX_MODELVIEW);
+
+ _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);
+ }
+
+ GE (ctx, glStencilMask (~(GLuint) 0));
+ GE (ctx, glDepthMask (TRUE));
+ GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE));
+
+ GE (ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1));
+ GE (ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP));
+
+ /* restore the original pipeline */
+ cogl_pop_source ();
+}
+
static void
disable_stencil_buffer (void)
{
@@ -689,9 +798,10 @@ _cogl_clip_stack_flush (CoglClipStack *stack,
_cogl_matrix_stack_push (modelview_stack);
_cogl_matrix_stack_set (modelview_stack, &path_entry->matrix);
- _cogl_add_path_to_stencil_buffer (path_entry->path,
- using_stencil_buffer,
- TRUE);
+ add_stencil_clip_path (framebuffer,
+ path_entry->path,
+ using_stencil_buffer,
+ TRUE);
_cogl_matrix_stack_pop (modelview_stack);
diff --git a/cogl/cogl-path-private.h b/cogl/cogl-path-private.h
index e85bf3a..bcdca49 100644
--- a/cogl/cogl-path-private.h
+++ b/cogl/cogl-path-private.h
@@ -112,4 +112,7 @@ _cogl_path_get_bounds (CoglPath *path,
gboolean
_cogl_path_is_rectangle (CoglPath *path);
+void
+_cogl_path_fill_nodes (CoglPath *path);
+
#endif /* __COGL_PATH_PRIVATE_H */
diff --git a/cogl/cogl2-path.c b/cogl/cogl2-path.c
index c2c478e..e3143a0 100644
--- a/cogl/cogl2-path.c
+++ b/cogl/cogl2-path.c
@@ -314,7 +314,7 @@ validate_layer_cb (CoglPipelineLayer *layer, void *user_data)
return !*needs_fallback;
}
-static void
+void
_cogl_path_fill_nodes (CoglPath *path)
{
gboolean needs_fallback = FALSE;
@@ -341,115 +341,6 @@ _cogl_path_fill_nodes (CoglPath *path)
}
void
-_cogl_add_path_to_stencil_buffer (CoglPath *path,
- gboolean merge,
- gboolean need_clear)
-{
- CoglPathData *data = path->data;
- CoglFramebuffer *framebuffer = cogl_get_draw_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);
-
- /* 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, FALSE);
-
- _cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, FALSE, 0);
-
- GE( ctx, glEnable (GL_STENCIL_TEST) );
-
- GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) );
- GE( ctx, glDepthMask (FALSE) );
-
- if (merge)
- {
- GE (ctx, glStencilMask (2));
- GE (ctx, glStencilFunc (GL_LEQUAL, 0x2, 0x6));
- }
- else
- {
- /* 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)
- /* 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_framebuffer_clear_without_flush4f is used instead
- of cogl_clear because it won't try to flush the journal */
- _cogl_framebuffer_clear_without_flush4f (framebuffer,
- COGL_BUFFER_BIT_STENCIL,
- 0, 0, 0, 0);
- else
- {
- /* Just clear the bounding box */
- GE( ctx, glStencilMask (~(GLuint) 0) );
- GE( ctx, glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) );
- _cogl_rectangle_immediate (data->path_nodes_min.x,
- data->path_nodes_min.y,
- data->path_nodes_max.x,
- data->path_nodes_max.y);
- }
- GE (ctx, glStencilMask (1));
- GE (ctx, glStencilFunc (GL_LEQUAL, 0x1, 0x3));
- }
-
- GE (ctx, glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT));
-
- if (path->data->path_nodes->len >= 3)
- _cogl_path_fill_nodes (path);
-
- if (merge)
- {
- /* Now we have the new stencil buffer in bit 1 and the old
- stencil buffer in bit 0 so we need to intersect them */
- GE (ctx, glStencilMask (3));
- GE (ctx, glStencilFunc (GL_NEVER, 0x2, 0x3));
- GE (ctx, glStencilOp (GL_DECR, GL_DECR, GL_DECR));
- /* Decrement all of the bits twice so that only pixels where the
- value is 3 will remain */
-
- _cogl_matrix_stack_push (projection_stack);
- _cogl_matrix_stack_load_identity (projection_stack);
- _cogl_matrix_stack_flush_to_gl (projection_stack,
- COGL_MATRIX_PROJECTION);
-
- _cogl_matrix_stack_push (modelview_stack);
- _cogl_matrix_stack_load_identity (modelview_stack);
- _cogl_matrix_stack_flush_to_gl (modelview_stack,
- COGL_MATRIX_MODELVIEW);
-
- _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);
- }
-
- GE (ctx, glStencilMask (~(GLuint) 0));
- GE (ctx, glDepthMask (TRUE));
- GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE));
-
- GE (ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1));
- GE (ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP));
-
- /* restore the original pipeline */
- cogl_pop_source ();
-}
-
-void
cogl2_path_fill (CoglPath *path)
{
g_return_if_fail (cogl_is_path (path));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]