From ca2844013e7c2d0bea48b4f2f2539306aace235f Mon Sep 17 00:00:00 2001
From: Robert Bragg <robert@linux.intel.com>
Date: Thu, 12 Mar 2009 14:16:48 +0000
Subject: [PATCH] Maintain the Cogl assumption that the modelview matrix is
 normally current

_cogl_add_path_to_stencil_buffer and _cogl_add_stencil_clip were leaving
the projection matrix current when calling cogl_rectangle which was
upsetting _cogl_current_matrix_state_flush.
---
 clutter/cogl/gl/cogl-primitives.c   | 16 +++++++++++++---
 clutter/cogl/gl/cogl.c              | 20 ++++++++++++++++----
 clutter/cogl/gles/cogl-primitives.c | 16 +++++++++++++---
 clutter/cogl/gles/cogl.c            | 20 ++++++++++++++++----
 4 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/clutter/cogl/gl/cogl-primitives.c b/clutter/cogl/gl/cogl-primitives.c
index 07e728beb..8195a3d60 100644
--- a/clutter/cogl/gl/cogl-primitives.c
+++ b/clutter/cogl/gl/cogl-primitives.c
@@ -198,18 +198,28 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
       GE( 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_current_matrix_push ();
-      _cogl_current_matrix_identity ();
 
       _cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
       _cogl_current_matrix_push ();
       _cogl_current_matrix_identity ();
+
+      /* Cogl generally assumes the modelview matrix is current, so since
+       * cogl_rectangle will be flushing GL state and emitting geometry
+       * to OpenGL it will be confused if we leave the projection matrix
+       * active... */
+      _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
+      _cogl_current_matrix_push ();
+      _cogl_current_matrix_identity ();
+
       cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
       cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
+
+      _cogl_current_matrix_pop ();
+
+      _cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
       _cogl_current_matrix_pop ();
 
       _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
-      _cogl_current_matrix_pop ();
     }
 
   GE( glStencilMask (~(GLuint) 0) );
diff --git a/clutter/cogl/gl/cogl.c b/clutter/cogl/gl/cogl.c
index 88ffb97df..ba92cba36 100644
--- a/clutter/cogl/gl/cogl.c
+++ b/clutter/cogl/gl/cogl.c
@@ -479,15 +479,27 @@ _cogl_add_stencil_clip (float x_offset,
 	 only pixels where both the original stencil buffer and the
 	 rectangle are set will be valid */
       GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) );
-      _cogl_current_matrix_push ();
-      _cogl_current_matrix_identity ();
+
       _cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
       _cogl_current_matrix_push ();
       _cogl_current_matrix_identity ();
-      cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
-      _cogl_current_matrix_pop ();
+
+      /* Cogl generally assumes the modelview matrix is current, so since
+       * cogl_rectangle will be flushing GL state and emitting geometry
+       * to OpenGL it will be confused if we leave the projection matrix
+       * active... */
       _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
+      _cogl_current_matrix_push ();
+      _cogl_current_matrix_identity ();
+
+      cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
+
       _cogl_current_matrix_pop ();
+
+      _cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
+      _cogl_current_matrix_pop ();
+
+      _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
     }
 
   /* Restore the stencil mode */
diff --git a/clutter/cogl/gles/cogl-primitives.c b/clutter/cogl/gles/cogl-primitives.c
index d1ba14372..ae91aa061 100644
--- a/clutter/cogl/gles/cogl-primitives.c
+++ b/clutter/cogl/gles/cogl-primitives.c
@@ -204,18 +204,28 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
       GE( 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_current_matrix_push ();
-      _cogl_current_matrix_identity ();
 
       _cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
       _cogl_current_matrix_push ();
       _cogl_current_matrix_identity ();
+
+      /* Cogl generally assumes the modelview matrix is current, so since
+       * cogl_rectangle will be flushing GL state and emitting geometry
+       * to OpenGL it will be confused if we leave the projection matrix
+       * active... */
+      _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
+      _cogl_current_matrix_push ();
+      _cogl_current_matrix_identity ();
+
       cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
       cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
+
+      _cogl_current_matrix_pop ();
+
+      _cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
       _cogl_current_matrix_pop ();
 
       _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
-      _cogl_current_matrix_pop ();
     }
 
   GE( glStencilMask (~(GLuint) 0) );
diff --git a/clutter/cogl/gles/cogl.c b/clutter/cogl/gles/cogl.c
index ca669e46d..47e84c5d8 100644
--- a/clutter/cogl/gles/cogl.c
+++ b/clutter/cogl/gles/cogl.c
@@ -421,15 +421,27 @@ _cogl_add_stencil_clip (float x_offset,
 	 only pixels where both the original stencil buffer and the
 	 rectangle are set will be valid */
       GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) );
-      _cogl_current_matrix_push ();
-      _cogl_current_matrix_identity ();
+
       _cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
       _cogl_current_matrix_push ();
       _cogl_current_matrix_identity ();
-      cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
-      _cogl_current_matrix_pop ();
+
+      /* Cogl generally assumes the modelview matrix is current, so since
+       * cogl_rectangle will be flushing GL state and emitting geometry
+       * to OpenGL it will be confused if we leave the projection matrix
+       * active... */
       _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
+      _cogl_current_matrix_push ();
+      _cogl_current_matrix_identity ();
+
+      cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
+
       _cogl_current_matrix_pop ();
+
+      _cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
+      _cogl_current_matrix_pop ();
+
+      _cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
     }
 
   /* Restore the stencil mode */