[cogl] clip-stack: Move path flushing code to cogl-clip-stack.c



commit fd2769f7e8e4432a99def75000f5bb4bf81c01fd
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.
    
    Reviewed-by: Neil Roberts <neil linux intel com>

 cogl/cogl-clip-stack.c   |  119 ++++++++++++++++++++++++++++++++++++++++++++-
 cogl/cogl-path-private.h |    3 +
 cogl/cogl2-path.c        |  114 +-------------------------------------------
 3 files changed, 120 insertions(+), 116 deletions(-)
---
diff --git a/cogl/cogl-clip-stack.c b/cogl/cogl-clip-stack.c
index 004445a..9fccc6d 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
@@ -274,6 +275,117 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
 }
 
 static 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,
+                           COGL_DRAW_SKIP_JOURNAL_FLUSH |
+                           COGL_DRAW_SKIP_PIPELINE_VALIDATION |
+                           COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
+
+  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)
 {
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@@ -689,9 +801,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 73eccbf..fd2e1de 100644
--- a/cogl/cogl-path-private.h
+++ b/cogl/cogl-path-private.h
@@ -113,4 +113,7 @@ _cogl_path_get_bounds (CoglPath *path,
 gboolean
 _cogl_path_is_rectangle (CoglPath *path);
 
+void
+_cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags);
+
 #endif /* __COGL_PATH_PRIVATE_H */
diff --git a/cogl/cogl2-path.c b/cogl/cogl2-path.c
index 8618f6f..fb421eb 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, CoglDrawFlags flags)
 {
   gboolean needs_fallback = FALSE;
@@ -339,118 +339,6 @@ _cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags)
 }
 
 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,
-                           COGL_DRAW_SKIP_JOURNAL_FLUSH |
-                           COGL_DRAW_SKIP_PIPELINE_VALIDATION |
-                           COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
-
-  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]