2007-05-28 Matthew Allum <mallum@openedhand.com>
authorMatthew Allum <mallum@openedhand.com>
Mon, 28 May 2007 18:49:34 +0000 (18:49 +0000)
committerMatthew Allum <mallum@openedhand.com>
Mon, 28 May 2007 18:49:34 +0000 (18:49 +0000)
        * clutter/clutter-backend.c:
        * clutter/clutter-backend.h:
        * clutter/glx/clutter-stage-glx.c:
        * clutter/glx/clutter-backend-glx.c:
        Fix up rendering pipeline removing clutter_backend_XXX_stage_paint
        and adding clutter_backend_XXX_redraw instead. Duplicates less
        code in backends, avoids clutter_actor_paint() getting called
        before stage is set up (viewport wise) and unbreaks things like
        picking.

        * clutter/clutter-actor.c:
        * clutter/clutter-actor.h:
        * clutter/clutter-main.c:
        * clutter/clutter-private.h:
        * clutter/clutter-stage.c: (clutter_stage_get_actor_at_pos):
        Redo picking functionality a different way (via color indexing)
        as to provide more flexibility, possibly speed and more likely
        work with GL/ES (doesn't currently however - not sure why).

        * clutter/clutter-group.c:
        Add groups own 'pick' method.

        * clutter/cogl/cogl.h:
        * clutter/cogl/gl/cogl.c:
        * clutter/cogl/gles/cogl.c:
        Move clipping funtionality into cogl.

        * clutter/cogl/gles/cogl-defines.h:
        Hack around missing BGR format in GL/ES.

        * clutter/egl/clutter-backend-egl.c:
        * clutter/egl/clutter-backend-egl.h:
        * clutter/egl/clutter-stage-egl.c:
        * clutter/sdl/clutter-backend-sdl.c:
        * clutter/sdl/clutter-backend-sdl.h:
        * clutter/sdl/clutter-event-sdl.c:
        * clutter/sdl/clutter-stage-sdl.c:
        Update backends to newer API.
        Add basic mouse event translation to SDL.

22 files changed:
ChangeLog
clutter/clutter-actor.c
clutter/clutter-actor.h
clutter/clutter-backend.c
clutter/clutter-backend.h
clutter/clutter-group.c
clutter/clutter-main.c
clutter/clutter-private.h
clutter/clutter-stage.c
clutter/cogl/cogl.h
clutter/cogl/gl/cogl.c
clutter/cogl/gles/cogl-defines.h
clutter/cogl/gles/cogl.c
clutter/egl/clutter-backend-egl.c
clutter/egl/clutter-backend-egl.h
clutter/egl/clutter-stage-egl.c
clutter/glx/clutter-backend-glx.c
clutter/glx/clutter-stage-glx.c
clutter/sdl/clutter-backend-sdl.c
clutter/sdl/clutter-backend-sdl.h
clutter/sdl/clutter-event-sdl.c
clutter/sdl/clutter-stage-sdl.c

index 822073e..eaeea71 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2007-05-28  Matthew Allum  <mallum@openedhand.com>
+
+       * clutter/clutter-backend.c:
+       * clutter/clutter-backend.h:
+       * clutter/glx/clutter-stage-glx.c:
+       * clutter/glx/clutter-backend-glx.c:
+       Fix up rendering pipeline removing clutter_backend_XXX_stage_paint
+       and adding clutter_backend_XXX_redraw instead. Duplicates less
+       code in backends, avoids clutter_actor_paint() getting called
+       before stage is set up (viewport wise) and unbreaks things like
+       picking.
+
+       * clutter/clutter-actor.c:
+       * clutter/clutter-actor.h:
+       * clutter/clutter-main.c:
+       * clutter/clutter-private.h:
+       * clutter/clutter-stage.c: (clutter_stage_get_actor_at_pos):
+       Redo picking functionality a different way (via color indexing)
+       as to provide more flexibility, possibly speed and more likely
+       work with GL/ES (doesn't currently however - not sure why).
+
+       * clutter/clutter-group.c:
+       Add groups own 'pick' method.
+
+       * clutter/cogl/cogl.h:
+       * clutter/cogl/gl/cogl.c:
+       * clutter/cogl/gles/cogl.c:
+       Move clipping funtionality into cogl.
+
+       * clutter/cogl/gles/cogl-defines.h:
+       Hack around missing BGR format in GL/ES.
+
+       * clutter/egl/clutter-backend-egl.c:
+       * clutter/egl/clutter-backend-egl.h:
+       * clutter/egl/clutter-stage-egl.c:
+       * clutter/sdl/clutter-backend-sdl.c:
+       * clutter/sdl/clutter-backend-sdl.h:
+       * clutter/sdl/clutter-event-sdl.c:
+       * clutter/sdl/clutter-stage-sdl.c:
+       Update backends to newer API.
+       Add basic mouse event translation to SDL.
+
 2007-05-25  Matthew Allum  <mallum@openedhand.com>
 
        * clutter/clutter-color.c: (clutter_color_parse):
index 5405d5b..364d1f1 100644 (file)
@@ -266,6 +266,40 @@ clutter_actor_unrealize (ClutterActor *self)
 }
 
 /**
+ * clutter_actor_pick:
+ * @self: A #ClutterActor
+ * @color: A #ClutterColor
+ *
+ * Renders a silhouette of the actor in supplied color.
+ *
+ * This function should not never be called directly by applications. 
+ **/
+void                  
+clutter_actor_pick (ClutterActor       *self, 
+                   const ClutterColor *color)
+{
+  ClutterActorClass *klass;
+
+  klass = CLUTTER_ACTOR_GET_CLASS (self);
+
+  if (G_UNLIKELY(klass->pick))
+    {
+      /* Its pretty unlikely anything other than a container actor 
+       * would need to supply its own pick method.
+      */
+      (klass->pick) (self, color);
+    }
+  else
+    {
+      cogl_color (color);
+      cogl_rectangle (0, 
+                     0, 
+                     clutter_actor_get_width(self), 
+                     clutter_actor_get_height(self));
+    }
+}
+
+/**
  * clutter_actor_paint:
  * @self: A #ClutterActor
  *
@@ -279,6 +313,7 @@ clutter_actor_paint (ClutterActor *self)
 {
   ClutterActorPrivate *priv;
   ClutterActorClass *klass;
+  ClutterMainContext *context;
 
   g_return_if_fail (CLUTTER_IS_ACTOR (self));
   priv = self->priv;
@@ -295,14 +330,11 @@ clutter_actor_paint (ClutterActor *self)
        }
     }
 
-  klass = CLUTTER_ACTOR_GET_CLASS (self);
+  context = clutter_context_get_default ();
+  klass   = CLUTTER_ACTOR_GET_CLASS (self);
 
   cogl_push_matrix();
 
-#if HAVE_COGL_GL
-  glLoadName (clutter_actor_get_id (self));
-#endif
-
   if (clutter_actor_get_parent (self) != NULL)
     {
       cogl_translate (CLUTTER_UNITS_TO_INT (priv->coords.x1), 
@@ -340,39 +372,35 @@ clutter_actor_paint (ClutterActor *self)
       cogl_scale (priv->scale_x, priv->scale_y);
     }
 
-#if HAVE_COGL_GL
   if (priv->has_clip)
-    {
-      ClutterGeometry *clip = &(priv->clip);
-
-      /* FIXME: ES ... */
-      glEnable (GL_STENCIL_TEST);
+    cogl_clip_set (&(priv->clip));
 
-      glClearStencil (0.0f);
-      glClear (GL_STENCIL_BUFFER_BIT);
-
-      glStencilFunc (GL_NEVER, 0x1, 0x1);
-      glStencilOp (GL_INCR, GL_INCR, GL_INCR);
+  if (G_UNLIKELY(context->pick_mode == TRUE))
+    {
+      ClutterColor col;
+      guint32      id;
 
-      glColor3f (1.0f, 1.0f, 1.0f);
+      id = clutter_actor_get_id (self);
 
-      glRecti (clip->x, 
-              clip->y,
-              clip->x + clip->width,
-              clip->y + clip->height);
+      /* Encode the actor id into a color */
+      col.red   = (id >> 16) & 0xff;
+      col.green = (id >> 8) & 0xff;
+      col.blue  =  id & 0xff;
+      col.alpha = 0xff;
 
-      glStencilFunc (GL_EQUAL, 0x1, 0x1);
-      glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
+      /* Actor will then paint silhouette of itself in supplied color.
+       * See clutter_stage_get_actor_at_pos() for where picking is enabled.  
+      */
+      clutter_actor_pick (self, &col);
+    }
+  else
+    {
+      if (G_LIKELY(klass->paint))
+       (klass->paint) (self);
     }
-#endif
-
-  if (klass->paint)
-    (klass->paint) (self);
 
-#if CLUTTER_COGL_GL
   if (priv->has_clip)
-    glDisable (GL_STENCIL_TEST);
-#endif
+    cogl_clip_unset();
 
   if (priv->scale_x != CFX_ONE || priv->scale_y != CFX_ONE)
     cogl_scale (CFX_ONE, CFX_ONE);
index ff8427c..37440cc 100644 (file)
@@ -31,6 +31,7 @@
 #include <glib-object.h>
 #include <clutter/clutter-fixed.h>
 #include <clutter/clutter-units.h>
+#include <clutter/clutter-color.h>
 
 G_BEGIN_DECLS
 
@@ -139,10 +140,8 @@ struct _ClutterActorClass
   void (* parent_set)      (ClutterActor        *actor,
                             ClutterActor        *old_parent);
 
-  void (* destroy)         (ClutterActor    *actor);
-
-  /* to go ? */
-  void (* queue_redraw)    (ClutterActor    *actor);
+  void (* destroy)         (ClutterActor        *actor);
+  void (* pick)            (ClutterActor        *actor, const ClutterColor *color);
 
   /* padding for future expansion */
   void (*_clutter_actor_1) (void);
@@ -161,6 +160,8 @@ void                  clutter_actor_hide_all         (ClutterActor          *sel
 void                  clutter_actor_realize          (ClutterActor          *self);
 void                  clutter_actor_unrealize        (ClutterActor          *self);
 void                  clutter_actor_paint            (ClutterActor          *self);
+void                  clutter_actor_pick             (ClutterActor        *actor, 
+                                                     const ClutterColor  *color);
 void                  clutter_actor_queue_redraw     (ClutterActor          *self);
 void                  clutter_actor_destroy          (ClutterActor          *self);
 void                  clutter_actor_request_coords   (ClutterActor          *self,
index 9b4c583..025cbc1 100644 (file)
@@ -143,6 +143,16 @@ _clutter_backend_init_stage (ClutterBackend  *backend,
   return TRUE;
 }
 
+void
+_clutter_backend_redraw (ClutterBackend *backend)
+{
+  ClutterBackendClass *klass;
+
+  klass = CLUTTER_BACKEND_GET_CLASS (backend);
+  if (G_LIKELY(klass->redraw))
+    klass->redraw (backend);
+}
+
 ClutterFeatureFlags
 _clutter_backend_get_features (ClutterBackend *backend)
 {
index 320d63a..a97507d 100644 (file)
@@ -68,6 +68,7 @@ struct _ClutterBackendClass
   void          (* add_options)   (ClutterBackend  *backend,
                                    GOptionGroup    *group);
   ClutterFeatureFlags (* get_features)  (ClutterBackend  *backend);
+  void                (* redraw)  (ClutterBackend *backend);
 };
 
 GType clutter_backend_get_type    (void) G_GNUC_CONST;
index 7b631cf..26b0d06 100644 (file)
@@ -46,6 +46,8 @@
 #include "clutter-marshal.h"
 #include "clutter-enum-types.h"
 
+#include "cogl.h"
+
 enum
 {
   ADD,
@@ -66,6 +68,7 @@ struct _ClutterGroupPrivate
   GList *children;
 };
 
+
 static void
 clutter_group_paint (ClutterActor *actor)
 {
@@ -93,6 +96,19 @@ clutter_group_paint (ClutterActor *actor)
   CLUTTER_NOTE (PAINT, "ClutterGroup paint leave");
 }
 
+static void                  
+clutter_group_pick (ClutterActor       *actor, 
+                   const ClutterColor *color)
+{
+  /* Just forward to the paint call which in turn will trigger 
+   * the child actors also getting 'picked'. To make ourselves
+   * 'sensitive' to clicks we could also paint a bounding rect
+   * but this is not currently done.  
+  */
+  clutter_group_paint (actor);
+}
+
+
 static void
 clutter_group_request_coords (ClutterActor        *self,
                              ClutterActorBox     *box)
@@ -224,6 +240,7 @@ clutter_group_class_init (ClutterGroupClass *klass)
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 
   actor_class->paint           = clutter_group_paint;
+  actor_class->pick            = clutter_group_pick;
   actor_class->show_all        = clutter_group_real_show_all;
   actor_class->hide_all        = clutter_group_real_hide_all;
   actor_class->request_coords  = clutter_group_request_coords;
index f24983d..77646db 100644 (file)
@@ -46,6 +46,8 @@
 #include "clutter-debug.h"
 #include "clutter-version.h"   /* For flavour define */
 
+#include "cogl.h"
+
 static ClutterMainContext *ClutterCntx = NULL;
 
 static gboolean clutter_is_initialized = FALSE;
@@ -94,10 +96,61 @@ void
 clutter_redraw (void)
 {
   ClutterMainContext *ctx;
+  ClutterColor        stage_color;
+  ClutterActor       *stage;
+  static GTimer      *timer = NULL; 
+  static guint        timer_n_frames = 0;
   
-  ctx = clutter_context_get_default ();
-  if (ctx->backend)
-    clutter_actor_paint (_clutter_backend_get_stage (ctx->backend));
+  ctx  = clutter_context_get_default ();
+
+  stage = _clutter_backend_get_stage (ctx->backend);
+
+  CLUTTER_NOTE (PAINT, " Redraw enter");
+
+  /* Setup FPS count */
+  if (clutter_get_show_fps ())
+    {
+      if (!timer)
+       timer = g_timer_new ();
+    }
+
+  /* The below cant go in stage paint as base actor_paint will get
+   * called before the below (and break picking etc)
+  */
+  if (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_SYNC_MATRICES)
+    {
+      cogl_setup_viewport (clutter_actor_get_width (stage),
+                          clutter_actor_get_height (stage),
+                          171, /* 60 degrees */
+                          CFX_ONE,
+                          CLUTTER_FLOAT_TO_FIXED (0.1),
+                          CLUTTER_FLOAT_TO_FIXED (100.0));
+    }
+
+  /* Setup the initial paint */
+  clutter_stage_get_color (CLUTTER_STAGE(stage), &stage_color);
+  cogl_paint_init (&stage_color);
+
+  /* Call through ti the actual backend to do the painting down from  
+   * the stage. It will likely need to swap buffers, vblank sync etc
+   * which will be windowing system dependant.
+  */
+  _clutter_backend_redraw (ctx->backend);
+
+  /* Complete FPS info */
+  if (clutter_get_show_fps ())
+    {
+      timer_n_frames++;
+
+      if (g_timer_elapsed (timer, NULL) >= 1.0)
+       {
+         g_print ("*** FPS: %i ***\n", timer_n_frames);
+         timer_n_frames = 0;
+         g_timer_start (timer);
+       }
+    }
+
+  CLUTTER_NOTE (PAINT, " Redraw leave");
 }
 
 /** 
@@ -271,7 +324,7 @@ clutter_get_debug_enabled (void)
 ClutterMainContext*
 clutter_context_get_default (void)
 {
-  if (!ClutterCntx)
+  if (G_UNLIKELY(!ClutterCntx))
     {
       ClutterMainContext *ctx;
 
index 64ad1b6..0844df7 100644 (file)
@@ -56,6 +56,7 @@ struct _ClutterMainContext
   guint            main_loop_level;
   GSList          *main_loops;
   guint            is_initialized : 1;
+  guint            pick_mode :1;
 };
 
 #define CLUTTER_CONTEXT()      (clutter_context_get_default ())
@@ -98,6 +99,8 @@ GType _clutter_backend_impl_get_type (void);
 
 ClutterActor *_clutter_backend_get_stage     (ClutterBackend  *backend);
 
+void          _clutter_backend_redraw        (ClutterBackend *backend);
+
 void          _clutter_backend_add_options   (ClutterBackend  *backend,
                                               GOptionGroup    *group);
 gboolean      _clutter_backend_pre_parse     (ClutterBackend  *backend,
index 083ea7e..87c3b83 100644 (file)
@@ -94,12 +94,9 @@ enum
 static guint stage_signals[LAST_SIGNAL] = { 0, };
 
 static void
-clutter_stage_paint (ClutterActor *actor)
+clutter_stage_paint (ClutterActor *self)
 {
-  /* chain up */
-  CLUTTER_NOTE (PAINT, "Chaining up to parent class paint");
-
-  CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (actor);
+  CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
 }
 
 static void
@@ -766,68 +763,41 @@ clutter_stage_get_actor_at_pos (ClutterStage *stage,
                                 gint          x,
                                 gint          y)
 {
-#if HAVE_COGL_GL
+  ClutterMainContext *context;
+  guchar              pixel[3];
+  GLint               viewport[4];
+  ClutterColor        white = { 0xff, 0xff, 0xff, 0xff };
+  guint32             id;
 
-  /* FIXME: Add a clutter feature flag for this or figure out  
-   *        for gles.
-  */
+  context = clutter_context_get_default ();
 
-  ClutterActor *found = NULL;
-  GLuint buff[512] = { 0 };
-  GLint hits;
-  GLint view[4];
-  
-  g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
-  glSelectBuffer (512, buff);
-  glGetIntegerv (GL_VIEWPORT, view);
-  glRenderMode (GL_SELECT);
-
-  glInitNames ();
-  glPushName (0);
-  glMatrixMode (GL_PROJECTION);
-  glPushMatrix ();
-  glLoadIdentity ();
-
-  /* This is gluPickMatrix(x, y, 1.0, 1.0, view); */
-  glTranslatef ((view[2] - 2 * (x - view[0])),
-               (view[3] - 2 * (y - view[1])), 0);
-  glScalef (view[2], -view[3], 1.0);
-
-  cogl_perspective (171, /* 60 degrees */
-                   CFX_ONE,
-                   CLUTTER_FLOAT_TO_FIXED (0.1),
-                   CLUTTER_FLOAT_TO_FIXED (100.0));
-
-  glMatrixMode (GL_MODELVIEW);
+  cogl_paint_init (&white);
+  cogl_enable (0);
 
+  /* Render the entire scence in pick mode - just single colored silhouette's  
+   * are drawn offscreen (as we never swap buffers)
+  */
+  context->pick_mode = TRUE;
   clutter_actor_paint (CLUTTER_ACTOR (stage));
+  context->pick_mode = FALSE;
 
-  glMatrixMode (GL_PROJECTION);
-  glPopMatrix ();
+  /* Calls should work under both GL and GLES 
+   *
+   * FIXME: of course we need to handle the case where the frame buffer isn't
+   * 24bpp, i.e 16bpp which could be the case with GLES.
+  */
+  glGetIntegerv(GL_VIEWPORT, viewport);
+  glReadPixels(x, viewport[3] - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
 
-  hits = glRenderMode (GL_RENDER);
+  /* printf("x: %i , y: %i %x:%x:%x\n", x, y, pixel[0], pixel[1], pixel[2]); */
 
-  if (hits != 0)
-    {
-#if 1
-      gint i;
-      for (i = 0; i < hits; i++)
-       g_print ("Hit at %i\n", buff[(hits-1) * 4 + 3]);
-#endif
-  
-      found = clutter_group_find_child_by_id (CLUTTER_GROUP (stage), 
-                                             buff[(hits-1) * 4 + 3]);
-    }
+  if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
+    return CLUTTER_ACTOR(stage);
 
-  CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
+  /* Decode color back into an ID */
+  id =  pixel[2] | pixel[1] << 8 | pixel[0] << 16;
 
-  return found;
-#else
-  /* GL/ES cannot do this yet.. */
-  return NULL;
-#endif
+  return clutter_group_find_child_by_id (CLUTTER_GROUP (stage), id);
 }
 
 /**
index 44b9d14..8093c44 100644 (file)
@@ -77,7 +77,7 @@ cogl_setup_viewport (guint        width,
                     ClutterFixed z_far);
 
 void
-cogl_paint_init (ClutterColor *color);
+cogl_paint_init (const ClutterColor *color);
 
 void
 cogl_push_matrix (void);
@@ -101,7 +101,13 @@ void
 cogl_rotate (gint angle, gint x, gint y, gint z);
 
 void
-cogl_color (ClutterColor *color);
+cogl_color (const ClutterColor *color);
+
+void
+cogl_clip_set (const ClutterGeometry *clip);
+
+void
+cogl_clip_unset (void);
 
 void
 cogl_enable (gulong flags);
index 91af4be..58c14a2 100644 (file)
@@ -139,7 +139,7 @@ cogl_check_extension (const gchar *name, const gchar *ext)
 }
 
 void
-cogl_paint_init (ClutterColor *color)
+cogl_paint_init (const ClutterColor *color)
 {
   GE( glClearColor (((float) color->red / 0xff * 1.0),
                    ((float) color->green / 0xff * 1.0),
@@ -266,11 +266,39 @@ cogl_enable (gulong flags)
 }
 
 void
-cogl_color (ClutterColor *color)
+cogl_color (const ClutterColor *color)
 {
   glColor4ub (color->red, color->green, color->blue, color->alpha);  
 }
 
+void
+cogl_clip_set (const ClutterGeometry *clip)
+{
+  GE( glEnable (GL_STENCIL_TEST) );
+
+  GE( glClearStencil (0.0f) );
+  GE( glClear (GL_STENCIL_BUFFER_BIT) );
+
+  GE( glStencilFunc (GL_NEVER, 0x1, 0x1) );
+  GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) );
+
+  GE( glColor3f (1.0f, 1.0f, 1.0f) );
+
+  GE( glRecti (clip->x, 
+              clip->y,
+              clip->x + clip->width,
+              clip->y + clip->height) );
+  
+  GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
+; GE(  glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
+}
+
+void
+cogl_clip_unset (void)
+{
+  GE( glDisable (GL_STENCIL_TEST) );
+}
+
 gboolean
 cogl_texture_can_size (COGLenum pixel_format,
                       COGLenum pixel_type,
@@ -423,7 +451,6 @@ cogl_trapezoid (gint y1,
   GE( glEnd () );
 }
 
-
 void
 cogl_alpha_func (COGLenum     func, 
                 ClutterFixed ref)
@@ -431,61 +458,6 @@ cogl_alpha_func (COGLenum     func,
   GE( glAlphaFunc (func, CLUTTER_FIXED_TO_FLOAT(ref)) );
 }
 
-#if 0
-/*
- * Original floating point implementaiton of the perspective function,
- * retained for reference purposes
- */
-static inline void
-frustum (GLfloat left,
-        GLfloat right,
-        GLfloat bottom,
-        GLfloat top,
-        GLfloat nearval,
-        GLfloat farval)
-{
-  GLfloat x, y, a, b, c, d;
-  GLfloat m[16];
-
-  x = (2.0 * nearval) / (right - left);
-  y = (2.0 * nearval) / (top - bottom);
-  a = (right + left) / (right - left);
-  b = (top + bottom) / (top - bottom);
-  c = -(farval + nearval) / ( farval - nearval);
-  d = -(2.0 * farval * nearval) / (farval - nearval);
-
-#define M(row,col)  m[col*4+row]
-  M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F;
-  M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F;
-  M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d;
-  M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F;
-#undef M
-
-  GE( glMultMatrixf (m) );
-}
-
-static inline void
-perspective (GLfloat fovy,
-            GLfloat aspect,
-            GLfloat zNear,
-            GLfloat zFar)
-{
-  GLfloat xmin, xmax, ymin, ymax;
-
-  ymax = zNear * tan (fovy * M_PI / 360.0);
-  ymin = -ymax;
-  xmin = ymin * aspect;
-  xmax = ymax * aspect;
-
-  printf ("%f, %f, %f, %f\n", xmin, xmax, ymin, ymax);
-  
-  frustum (xmin, xmax, ymin, ymax, zNear, zFar);
-}
-#endif
-
-/*
- * Fixed point implementation of the perspective function
- */
 void
 cogl_perspective (ClutterAngle fovy,
                  ClutterFixed aspect,
@@ -495,11 +467,7 @@ cogl_perspective (ClutterAngle fovy,
   ClutterFixed xmax, ymax;
   ClutterFixed x, y, c, d;
 
-#ifdef HAVE_COGL_GL
   GLfloat m[16];
-#else
-  GLfixed m[16];
-#endif
   
   memset (&m[0], 0, sizeof (m));
 
@@ -521,7 +489,6 @@ cogl_perspective (ClutterAngle fovy,
   d = CFX_DIV (-(clutter_qmulx (2*zFar, zNear)), (zFar - zNear));
 
 #define M(row,col)  m[col*4+row]
-#ifdef HAVE_COGL_GL
   M(0,0) = CLUTTER_FIXED_TO_FLOAT (x);
   M(1,1) = CLUTTER_FIXED_TO_FLOAT (y);
   M(2,2) = CLUTTER_FIXED_TO_FLOAT (c);
@@ -529,15 +496,6 @@ cogl_perspective (ClutterAngle fovy,
   M(3,2) = -1.0F;
   
   GE( glMultMatrixf (m) );
-#else
-  M(0,0) = x;
-  M(1,1) = y;
-  M(2,2) = c;
-  M(2,3) = d;
-  M(3,2) = 1 + ~CFX_ONE;
-  
-  GE( glMultMatrixx (m) );
-#endif
 #undef M
 }
 
@@ -568,7 +526,7 @@ cogl_setup_viewport (guint        width,
 
   GE( glTranslatef (-0.5f, -0.5f, -z_camera) );
   GE( glScalef ( 1.0f / width, 
-           -1.0f / height, 
+           -1.0f / height, 
                 1.0f / width) );
   GE( glTranslatef (0.0f, -1.0 * height, 0.0f) );
 }
index 69112a1..84d2cf6 100644 (file)
@@ -444,6 +444,13 @@ typedef GLint  COGLint;
 
 #define CGL_TEXTURE_2D GL_TEXTURE_2D
 #define CGL_ARGB GL_ARGB
+
+/* FIXME: There is no BGR support in GLES - so with below BGR textures are 
+ * borked. Will likely need a feature flag and some coversion..
+ */
+#define CGL_BGR GL_RGB
+#define CGL_BGRA GL_RGBA
+
 #define CGL_TEXTURE_RECTANGLE_ARB 0 /* Its unlikely we support this */
 
 G_END_DECLS
index 1335724..fa8b2c0 100644 (file)
@@ -100,7 +100,7 @@ cogl_check_extension (const gchar *name, const gchar *ext)
 }
 
 void
-cogl_paint_init (ClutterColor *color)
+cogl_paint_init (const ClutterColor *color)
 {
 #if COGL_DEBUG
   fprintf(stderr, "\n ============== Paint Start ================ \n");
@@ -234,7 +234,7 @@ cogl_enable (gulong flags)
 }
 
 void
-cogl_color (ClutterColor *color)
+cogl_color (const ClutterColor *color)
 {
   GE( glColor4x ((color->red << 16) / 0xff, 
                 (color->green << 16) / 0xff,
@@ -242,19 +242,45 @@ cogl_color (ClutterColor *color)
                 (color->alpha << 16) / 0xff) );  
 }
 
+void
+cogl_clip_set (const ClutterGeometry *clip)
+{
+  GE( glEnable (GL_STENCIL_TEST) );
+
+  GE( glClearStencil (0) );
+  GE( glClear (GL_STENCIL_BUFFER_BIT) );
+
+  GE( glStencilFunc (GL_NEVER, 0x1, 0x1) );
+  GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) );
+
+  GE( glColor4x (CFX_ONE, CFX_ONE, CFX_ONE, CFX_ONE ) );
+
+  cogl_rectangle (clip->x, clip->y, clip->width, clip->height);
+  
+  GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
+  GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
+}
+
+void
+cogl_clip_unset (void)
+{
+  GE( glDisable (GL_STENCIL_TEST) );
+}
+
+
+
 gboolean
 cogl_texture_can_size (COGLenum pixel_format,
                       COGLenum pixel_type,
                       int    width, 
                       int    height)
 {
-  GLint new_width = 0;
-
-
   /* FIXME */
   return TRUE;
 
 #if 0
+  GLint new_width = 0;
+
   GE( glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
                    width, height, 0 /* border */,
                    pixel_format, pixel_type, NULL) );
@@ -433,8 +459,6 @@ cogl_alpha_func (COGLenum     func,
   GE( glAlphaFunc (func, CLUTTER_FIXED_TO_FLOAT(ref)) );
 }
 
-
-
 /*
  * Fixed point implementation of the perspective function
  */
@@ -507,8 +531,15 @@ cogl_setup_viewport (guint         w,
   /* camera distance from screen, 0.5 * tan (FOV) */
 #define DEFAULT_Z_CAMERA 0.866025404f
   z_camera = clutter_tani (fovy) << 1;
-  
-  GE( glTranslatex (-1 << 15, -1 << 15, -z_camera );
+
+  /*  
+  printf("%i vs %i\n", 
+        CLUTTER_FLOAT_TO_FIXED(DEFAULT_Z_CAMERA),
+        clutter_tani (fovy) << 1);
+  */
+
+  GE( glTranslatex (-1 << 15, -1 << 15, /*-z_camera*/
+                   -CLUTTER_FLOAT_TO_FIXED(DEFAULT_Z_CAMERA)));
 
   GE( glScalex ( CFX_ONE / width, 
                 -CFX_ONE / height,
index 67f23a2..6eb7850 100644 (file)
@@ -166,6 +166,30 @@ static const GOptionEntry entries[] =
   { NULL }
 };
 
+static void
+clutter_backend_egl_redraw (ClutterBackend *backend)
+{
+  ClutterBackendEgl *backend_egl = CLUTTER_BACKEND_EGL (backend);
+  ClutterStageEgl   *stage_egl;
+
+  stage_egl = CLUTTER_STAGE_EGL(backend_egl->stage);
+
+  clutter_actor_paint (CLUTTER_ACTOR(stage_egl));
+
+  /* Why this paint is done in backend as likely GL windowing system
+   * specific calls, like swapping buffers.
+  */
+  if (stage_egl->xwin)
+    {
+      /* clutter_feature_wait_for_vblank (); */
+      eglSwapBuffers ((EGLDisplay)stage_egl->xdpy,  stage_egl->egl_surface);
+    }
+  else
+    {
+      eglWaitGL ();
+      CLUTTER_GLERR ();
+    }
+}
 
 static void
 clutter_backend_egl_add_options (ClutterBackend *backend,
@@ -237,7 +261,6 @@ clutter_backend_egl_constructor (GType                  gtype,
   return g_object_ref (backend_singleton);
 }
 
-
 static void
 clutter_backend_egl_class_init (ClutterBackendEglClass *klass)
 {
@@ -248,12 +271,13 @@ clutter_backend_egl_class_init (ClutterBackendEglClass *klass)
   gobject_class->dispose = clutter_backend_egl_dispose;
   gobject_class->finalize = clutter_backend_egl_finalize;
 
-  backend_class->pre_parse = clutter_backend_egl_pre_parse;
-  backend_class->post_parse = clutter_backend_egl_post_parse;
-  backend_class->init_stage = clutter_backend_egl_init_stage;
+  backend_class->pre_parse   = clutter_backend_egl_pre_parse;
+  backend_class->post_parse  = clutter_backend_egl_post_parse;
+  backend_class->init_stage  = clutter_backend_egl_init_stage;
   backend_class->init_events = clutter_backend_egl_init_events;
-  backend_class->get_stage = clutter_backend_egl_get_stage;
+  backend_class->get_stage   = clutter_backend_egl_get_stage;
   backend_class->add_options = clutter_backend_egl_add_options;
+  backend_class->redraw      = clutter_backend_egl_redraw;
 }
 
 static void
index a80182b..812490b 100644 (file)
@@ -72,6 +72,9 @@ struct _ClutterBackendEglClass
 
 GType clutter_backend_egl_get_type (void) G_GNUC_CONST;
 
+void _clutter_events_init (ClutterBackend *backend);
+void _clutter_events_uninit (ClutterBackend *backend);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_BACKEND_EGL_H__ */
index 809c71b..8358797 100644 (file)
@@ -182,60 +182,7 @@ clutter_stage_egl_realize (ClutterActor *actor)
       /* FIXME */
     }
 
-  _clutter_stage_sync_viewport (CLUTTER_STAGE (stage_egl));
-}
-
-static void
-clutter_stage_egl_paint (ClutterActor *self)
-{
-  ClutterStageEgl *stage_egl = CLUTTER_STAGE_EGL (self);
-  ClutterStage    *stage = CLUTTER_STAGE (self);
-  ClutterColor     stage_color;
-  static GTimer   *timer = NULL; 
-  static guint     timer_n_frames = 0;
-
-  CLUTTER_NOTE (PAINT, " Redraw enter");
-
-  if (clutter_get_show_fps ())
-    {
-      if (!timer)
-       timer = g_timer_new ();
-    }
-
-  clutter_stage_get_color (stage, &stage_color);
-
-  cogl_paint_init (&stage_color);
-
-  /* Basically call up to ClutterGroup paint here */
-  CLUTTER_ACTOR_CLASS (clutter_stage_egl_parent_class)->paint (self);
-
-  /* Why this paint is done in backend as likely GL windowing system
-   * specific calls, like swapping buffers.
-  */
-  if (stage_egl->xwin)
-    {
-      /* clutter_feature_wait_for_vblank (); */
-      eglSwapBuffers ((EGLDisplay)stage_egl->xdpy,  stage_egl->egl_surface);
-    }
-  else
-    {
-      eglWaitGL ();
-      CLUTTER_GLERR ();
-    }
-
-  if (clutter_get_show_fps ())
-    {
-      timer_n_frames++;
-
-      if (g_timer_elapsed (timer, NULL) >= 1.0)
-       {
-         g_print ("*** FPS: %i ***\n", timer_n_frames);
-         timer_n_frames = 0;
-         g_timer_start (timer);
-       }
-    }
-
-  CLUTTER_NOTE (PAINT, " Redraw leave");
+  CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
 }
 
 static void
@@ -272,7 +219,7 @@ clutter_stage_egl_request_coords (ClutterActor        *self,
                       stage_egl->xwin_width,
                       stage_egl->xwin_height);
 
-      _clutter_stage_sync_viewport (CLUTTER_STAGE (stage_egl));
+      CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
     }
 
   if (stage_egl->xwin != None) /* Do we want to bother ? */
@@ -316,7 +263,7 @@ clutter_stage_egl_set_fullscreen (ClutterStage *stage,
         XDeleteProperty (stage_egl->xdpy, stage_egl->xwin, atom_WM_STATE);
     }
 
-  _clutter_stage_sync_viewport (stage);
+  CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
 }
 
 static void
@@ -359,8 +306,6 @@ clutter_stage_egl_set_cursor_visible (ClutterStage *stage,
       XDefineCursor (stage_egl->xdpy, stage_egl->xwin, curs);
 #endif /* HAVE_XFIXES */
     }
-
-  _clutter_stage_sync_viewport (stage);
 }
 
 static void
@@ -372,13 +317,6 @@ clutter_stage_egl_set_offscreen (ClutterStage *stage,
 }
 
 static void
-snapshot_pixbuf_free (guchar   *pixels,
-                     gpointer  data)
-{
-  g_free (pixels);
-}
-
-static void
 clutter_stage_egl_draw_to_pixbuf (ClutterStage *stage,
                                   GdkPixbuf    *dest,
                                   gint          x,
@@ -414,7 +352,6 @@ clutter_stage_egl_class_init (ClutterStageEglClass *klass)
   actor_class->hide = clutter_stage_egl_hide;
   actor_class->realize = clutter_stage_egl_realize;
   actor_class->unrealize = clutter_stage_egl_unrealize;
-  actor_class->paint = clutter_stage_egl_paint;
   actor_class->request_coords = clutter_stage_egl_request_coords;
   actor_class->allocate_coords = clutter_stage_egl_allocate_coords;
   
index 378a5de..be2bdef 100644 (file)
@@ -469,6 +469,33 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
 }
 
 static void
+clutter_backend_glx_redraw (ClutterBackend *backend)
+{
+  ClutterBackendGlx *backend_glx = CLUTTER_BACKEND_GLX (backend);
+  ClutterStageGlx   *stage_glx;
+
+  stage_glx = CLUTTER_STAGE_GLX(backend_glx->stage);
+
+  clutter_actor_paint (CLUTTER_ACTOR(stage_glx));
+
+  /* Why this paint is done in backend as likely GL windowing system
+   * specific calls, like swapping buffers.
+  */
+  if (stage_glx->xwin)
+    {
+      clutter_backend_glx_wait_for_vblank (stage_glx->backend);
+      glXSwapBuffers (stage_glx->xdpy, stage_glx->xwin);
+    }
+  else
+    {
+      /* offscreen */
+      glXWaitGL ();
+      CLUTTER_GLERR ();
+    }
+
+}
+
+static void
 clutter_backend_glx_class_init (ClutterBackendGlxClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -478,13 +505,14 @@ clutter_backend_glx_class_init (ClutterBackendGlxClass *klass)
   gobject_class->dispose = clutter_backend_glx_dispose;
   gobject_class->finalize = clutter_backend_glx_finalize;
 
-  backend_class->pre_parse = clutter_backend_glx_pre_parse;
-  backend_class->post_parse = clutter_backend_glx_post_parse;
-  backend_class->init_stage = clutter_backend_glx_init_stage;
-  backend_class->init_events = clutter_backend_glx_init_events;
-  backend_class->get_stage = clutter_backend_glx_get_stage;
-  backend_class->add_options = clutter_backend_glx_add_options;
+  backend_class->pre_parse   = clutter_backend_glx_pre_parse;
+  backend_class->post_parse   = clutter_backend_glx_post_parse;
+  backend_class->init_stage   = clutter_backend_glx_init_stage;
+  backend_class->init_events  = clutter_backend_glx_init_events;
+  backend_class->get_stage    = clutter_backend_glx_get_stage;
+  backend_class->add_options  = clutter_backend_glx_add_options;
   backend_class->get_features = clutter_backend_glx_get_features;
+  backend_class->redraw       = clutter_backend_glx_redraw;
 }
 
 static void
index 7c2692a..ee7cbce 100644 (file)
@@ -306,72 +306,6 @@ clutter_stage_glx_realize (ClutterActor *actor)
 }
 
 static void
-clutter_stage_glx_paint (ClutterActor *self)
-{
-  ClutterStageGlx *stage_glx = CLUTTER_STAGE_GLX (self);
-  ClutterStage    *stage = CLUTTER_STAGE (self);
-  ClutterColor     stage_color;
-  static GTimer   *timer = NULL; 
-  static guint     timer_n_frames = 0;
-
-  CLUTTER_NOTE (PAINT, " Redraw enter");
-
-  /* Setup FPS count */
-  if (clutter_get_show_fps ())
-    {
-      if (!timer)
-       timer = g_timer_new ();
-    }
-
-  /* Reset view matrices if needed. */
-  if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_SYNC_MATRICES)
-    {
-      cogl_setup_viewport (clutter_actor_get_width (self),
-                          clutter_actor_get_height (self),
-                          171, /* 60 degrees */
-                          CFX_ONE,
-                          CLUTTER_FLOAT_TO_FIXED (0.1),
-                          CLUTTER_FLOAT_TO_FIXED (100.0));
-    }
-
-  /* Setup the initial paint */
-  clutter_stage_get_color (stage, &stage_color);
-  cogl_paint_init (&stage_color);
-
-  /* chain up to reach ClutterGroup->paint here and actually paint all */
-  CLUTTER_ACTOR_CLASS (clutter_stage_glx_parent_class)->paint (self);
-
-  /* Why this paint is done in backend as likely GL windowing system
-   * specific calls, like swapping buffers.
-  */
-  if (stage_glx->xwin)
-    {
-      clutter_backend_glx_wait_for_vblank (stage_glx->backend);
-      glXSwapBuffers (stage_glx->xdpy, stage_glx->xwin);
-    }
-  else
-    {
-      glXWaitGL ();
-      CLUTTER_GLERR ();
-    }
-
-  /* Complete FPS info */
-  if (clutter_get_show_fps ())
-    {
-      timer_n_frames++;
-
-      if (g_timer_elapsed (timer, NULL) >= 1.0)
-       {
-         g_print ("*** FPS: %i ***\n", timer_n_frames);
-         timer_n_frames = 0;
-         g_timer_start (timer);
-       }
-    }
-
-  CLUTTER_NOTE (PAINT, " Redraw leave");
-}
-
-static void
 clutter_stage_glx_allocate_coords (ClutterActor        *self,
                                    ClutterActorBox     *box)
 {
@@ -600,7 +534,6 @@ clutter_stage_glx_class_init (ClutterStageGlxClass *klass)
   actor_class->hide = clutter_stage_glx_hide;
   actor_class->realize = clutter_stage_glx_realize;
   actor_class->unrealize = clutter_stage_glx_unrealize;
-  actor_class->paint = clutter_stage_glx_paint;
   actor_class->request_coords = clutter_stage_glx_request_coords;
   actor_class->allocate_coords = clutter_stage_glx_allocate_coords;
   
index f9aa04c..6447f92 100644 (file)
@@ -114,6 +114,19 @@ clutter_backend_sdl_get_stage (ClutterBackend *backend)
 }
 
 static void
+clutter_backend_sdl_redraw (ClutterBackend *backend)
+{
+  ClutterBackendSDL *backend_sdl = CLUTTER_BACKEND_SDL (backend);
+  ClutterStageSDL   *stage_sdl;
+
+  stage_sdl = CLUTTER_STAGE_SDL(backend_sdl->stage);
+
+  clutter_actor_paint (CLUTTER_ACTOR(stage_sdl));
+  
+  SDL_GL_SwapBuffers();
+}
+
+static void
 clutter_backend_sdl_finalize (GObject *gobject)
 {
   SDL_Quit();
@@ -181,6 +194,7 @@ clutter_backend_sdl_class_init (ClutterBackendSDLClass *klass)
   backend_class->init_events = clutter_backend_sdl_init_events;
   backend_class->get_stage = clutter_backend_sdl_get_stage;
   backend_class->add_options = clutter_backend_sdl_add_options;
+  backend_class->redraw      = clutter_backend_sdl_redraw;
 }
 
 static void
index bc9de1e..49b0e12 100644 (file)
@@ -58,6 +58,9 @@ struct _ClutterBackendSDLClass
 
 GType clutter_backend_sdl_get_type (void) G_GNUC_CONST;
 
+void _clutter_events_init (ClutterBackend *backend);
+void _clutter_events_uninit (ClutterBackend *backend);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_BACKEND_SDL_H__ */
index 18d60ca..c6408e8 100644 (file)
@@ -124,12 +124,101 @@ clutter_event_check (GSource *source)
 }
 
 static gboolean
+event_translate (ClutterBackend *backend,
+                ClutterEvent   *event,
+                SDL_Event      *sdl_event)
+{
+  /* FIXME: Complete */
+  gboolean res;
+
+  res = TRUE;
+
+  switch (sdl_event->type) 
+    {
+
+    case SDL_MOUSEBUTTONDOWN:
+      switch (sdl_event->button.button)
+        {
+        case 4: /* up */
+        case 5: /* down */
+        case 6: /* left */
+        case 7: /* right */
+          event->scroll.type = event->type = CLUTTER_SCROLL;
+
+          if (sdl_event->button.button == 4)
+            event->scroll.direction = CLUTTER_SCROLL_UP;
+          else if (sdl_event->button.button == 5)
+            event->scroll.direction = CLUTTER_SCROLL_DOWN;
+          else if (sdl_event->button.button == 6)
+            event->scroll.direction = CLUTTER_SCROLL_LEFT;
+          else
+            event->scroll.direction = CLUTTER_SCROLL_RIGHT;
+          
+          event->scroll.time = 0;
+          event->scroll.x = sdl_event->button.x;
+          event->scroll.y = sdl_event->button.y;
+          event->scroll.modifier_state = sdl_event->button.state;
+
+          break;
+        default:
+          event->button.type = event->type = CLUTTER_BUTTON_PRESS;
+          event->button.time = 0;
+          event->button.x = sdl_event->button.x;
+          event->button.y = sdl_event->button.y;
+          event->button.modifier_state = sdl_event->button.state;
+          event->button.button = sdl_event->button.button;
+          _clutter_event_button_generate (backend, event);
+          break;
+        }
+      break;
+
+    case SDL_MOUSEBUTTONUP:
+      /* scroll events don't have a corresponding release */
+      if (sdl_event->button.button == 4 ||
+          sdl_event->button.button == 5 ||
+          sdl_event->button.button == 6 ||
+          sdl_event->button.button == 7)
+        {
+          res = FALSE;
+          break;
+        }
+
+      event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
+      event->button.time = 0;
+      event->button.x = sdl_event->button.x;
+      event->button.y = sdl_event->button.y;
+      event->button.modifier_state = sdl_event->button.state;
+      event->button.button = sdl_event->button.button;
+      break;
+
+    case SDL_MOUSEMOTION:
+      event->motion.type = event->type = CLUTTER_MOTION;
+      event->motion.time = 0;
+      event->motion.x = sdl_event->motion.x;
+      event->motion.y = sdl_event->motion.y;
+      event->motion.modifier_state = sdl_event->motion.state;;
+      break;
+
+    default:
+      res = FALSE;
+      break;
+    }
+
+  return res;
+}
+
+
+static gboolean
 clutter_event_dispatch (GSource     *source,
                         GSourceFunc  callback,
                         gpointer     user_data)
 {
   SDL_Event       sdl_event;
   ClutterEvent   *event = NULL;
+  ClutterBackend *backend = ((ClutterEventSource *) source)->backend;
+  ClutterMainContext  *clutter_context;
+
+  clutter_context = clutter_context_get_default ();
 
   while (SDL_PollEvent(&sdl_event))
     {
@@ -141,11 +230,22 @@ clutter_event_dispatch (GSource     *source,
          SDL_Quit();
          exit(0);
        }
+      else 
+       {
+         event = clutter_event_new (CLUTTER_NOTHING);
 
+         if (event_translate (backend, event, &sdl_event))
+           {
+             /* push directly here to avoid copy of queue_put */
+             g_queue_push_head (clutter_context->events_queue, event);
+           }
+         else
+           {
+             clutter_event_free (event);
+           }
+       }
     }
 
-  return TRUE;
-
   event = clutter_event_get ();
 
   if (event)
index b8eeee6..6fd01ac 100644 (file)
@@ -77,51 +77,7 @@ clutter_stage_sdl_realize (ClutterActor *actor)
       return;
     }
 
-  _clutter_stage_sync_viewport (CLUTTER_STAGE (stage_sdl));
-}
-
-static void
-clutter_stage_sdl_paint (ClutterActor *self)
-{
-  ClutterStage    *stage = CLUTTER_STAGE (self);
-  ClutterColor     stage_color;
-  static GTimer   *timer = NULL; 
-  static guint     timer_n_frames = 0;
-
-  CLUTTER_NOTE (PAINT, " Redraw enter");
-
-  if (clutter_get_show_fps ())
-    {
-      if (!timer)
-       timer = g_timer_new ();
-    }
-
-  clutter_stage_get_color (stage, &stage_color);
-
-  cogl_paint_init (&stage_color);
-
-  /* Basically call up to ClutterGroup paint here */
-  CLUTTER_ACTOR_CLASS (clutter_stage_sdl_parent_class)->paint (self);
-
-  /* Why this paint is done in backend as likely GL windowing system
-   * specific calls, like swapping buffers.
-  */
-  
-  SDL_GL_SwapBuffers();
-
-  if (clutter_get_show_fps ())
-    {
-      timer_n_frames++;
-
-      if (g_timer_elapsed (timer, NULL) >= 1.0)
-       {
-         g_print ("*** FPS: %i ***\n", timer_n_frames);
-         timer_n_frames = 0;
-         g_timer_start (timer);
-       }
-    }
-
-  CLUTTER_NOTE (PAINT, " Redraw leave");
+  CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
 }
 
 static void
@@ -163,7 +119,7 @@ clutter_stage_sdl_request_coords (ClutterActor    *self,
       stage_sdl->win_width  = new_width;
       stage_sdl->win_height = new_height;
 
-      _clutter_stage_sync_viewport (CLUTTER_STAGE (stage_sdl));
+      CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
     }
 }
 
@@ -231,7 +187,6 @@ clutter_stage_sdl_class_init (ClutterStageSDLClass *klass)
   actor_class->hide = clutter_stage_sdl_hide;
   actor_class->realize = clutter_stage_sdl_realize;
   actor_class->unrealize = clutter_stage_sdl_unrealize;
-  actor_class->paint = clutter_stage_sdl_paint;
   actor_class->request_coords = clutter_stage_sdl_request_coords;
   actor_class->allocate_coords = clutter_stage_sdl_allocate_coords;