2006-11-15 Matthew Allum <mallum@openedhand.com>
authorMatthew Allum <mallum@openedhand.com>
Wed, 15 Nov 2006 21:19:01 +0000 (21:19 +0000)
committerMatthew Allum <mallum@openedhand.com>
Wed, 15 Nov 2006 21:19:01 +0000 (21:19 +0000)
        * clutter/clutter-actor.h:
        * clutter/clutter-actor.c:
        Add new API clutter_actor_move_by(), clutter_actor_get_size()

        * clutter/clutter-alpha.c:
        * clutter/clutter-alpha.h:
        Add clutter alpha sine func

        * clutter/clutter-behaviours.h:
        * clutter/clutter-behaviours.c:
        Add a basic scale behaviour (needs work)

        * examples/behave.c: (main):
        More playing with new behaviour functionality

        * clutter/clutter-feature.c:
        * clutter/clutter-feature.h:
        * clutter/clutter-main.c:
        Add new experimental sync to vblank code
        Set env CLUTTER_VBLANK=none to disable.

clutter/clutter-actor.c
clutter/clutter-actor.h
clutter/clutter-alpha.c
clutter/clutter-alpha.h
clutter/clutter-behaviours.c
clutter/clutter-behaviours.h
clutter/clutter-feature.c
clutter/clutter-feature.h
clutter/clutter-main.c

index e470286..70aeaa7 100644 (file)
@@ -875,6 +875,36 @@ clutter_actor_set_position (ClutterActor *self,
 }
 
 /**
+ * clutter_actor_move_by
+ * @self: A #ClutterActor
+ * @dx: Distance to move Actor on X axis.
+ * @dy: Distance to move Actor on Y axis.
+ *
+ * Moves an actor by specified distance relative to 
+ * current position.
+ *
+ * Since: 0.2
+ */
+void
+clutter_actor_move_by (ClutterActor *self,
+                      gint          dx,
+                      gint          dy)
+{
+  ClutterActorBox box;
+
+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
+
+  clutter_actor_allocate_coords (self, &box);
+
+  box.x2 += dx;
+  box.y2 += dy;
+  box.x1 += dx;
+  box.y1 += dy;
+
+  clutter_actor_request_coords (self, &box);
+}
+
+/**
  * clutter_actor_set_size
  * @self: A #ClutterActor
  * @width: New width of actor in pixels 
@@ -900,6 +930,29 @@ clutter_actor_set_size (ClutterActor *self,
   clutter_actor_request_coords (self, &box);
 }
 
+/*
+ * clutter_actor_get_size
+ * @self: A #ClutterActor
+ * @x: Location to store width if non NULL.
+ * @y: Location to store height if non NULL.
+ *
+ * Gets the size of an actor ignoring any scaling factors
+ *
+ * Since: 0.2
+ */
+void
+clutter_actor_get_size (ClutterActor *self,
+                       guint        *width,
+                       guint        *height)
+{
+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
+
+  if (width)
+    *width = clutter_actor_get_width(self);
+  if (height)
+    *height = clutter_actor_get_height(self);
+}
+
 /**
  * clutter_actor_get_abs_position
  * @self: A #ClutterActor
index d4c3070..8ef61b5 100644 (file)
@@ -237,6 +237,16 @@ clutter_actor_get_abs_size (ClutterActor *self,
                            guint        *width,
                            guint        *height);
 
+void
+clutter_actor_get_size (ClutterActor *self,
+                       guint        *width,
+                       guint        *height);
+
+void
+clutter_actor_move_by (ClutterActor *self,
+                      gint          dx,
+                      gint          dy);
+
 G_END_DECLS
 
 #endif
index 61ebbbe..e3723eb 100644 (file)
@@ -37,6 +37,7 @@
 #include "clutter-alpha.h"
 #include "clutter-main.h"
 #include "clutter-marshal.h"
+#include <math.h>
 
 G_DEFINE_TYPE (ClutterAlpha, clutter_alpha, G_TYPE_OBJECT);
 
@@ -105,6 +106,26 @@ clutter_alpha_ramp_func (ClutterAlpha *alpha)
     }
 }
 
+guint32 
+clutter_alpha_sine_func (ClutterAlpha *alpha)
+{
+  int    current_frame_num, nframes;
+  double x;
+
+  current_frame_num =
+          clutter_timeline_get_current_frame (alpha->priv->timeline);
+  nframes =
+          clutter_timeline_get_n_frames (alpha->priv->timeline);
+
+  /* FIXME: fixed point, and fixed point sine() */
+
+  x = (double)(current_frame_num * 2.0f * M_PI) / nframes ;
+
+  printf("%2f\n", ((sin(x-(M_PI/2.0f)) + 1.0f ) * 0.5f )); 
+
+  return (guint32) (((sin(x-(M_PI/2.0f)) + 1.0f ) * 0.5f ) * (double)CLUTTER_ALPHA_MAX_ALPHA);  
+}
+
 /* Object */
 
 static void
index 6db4ff3..5761440 100644 (file)
@@ -112,9 +112,13 @@ clutter_alpha_ramp_dec_func (ClutterAlpha *alpha);
 guint32 
 clutter_alpha_ramp_func (ClutterAlpha *alpha);
 
+guint32 
+clutter_alpha_sine_func (ClutterAlpha *alpha);
+
 #define CLUTTER_ALPHA_RAMP_INC clutter_alpha_ramp_inc_func
 #define CLUTTER_ALPHA_RAMP_DEC clutter_alpha_ramp_dec_func
 #define CLUTTER_ALPHA_RAMP     clutter_alpha_ramp_func
+#define CLUTTER_ALPHA_SINE     clutter_alpha_sine_func
 
 G_END_DECLS
 
index be82cbf..e70587b 100644 (file)
 
 /**
  * SECTION:clutter-behaviour
- * @short_description: Class for providing behaviours to actors
+ * @short_description: Class for providing common behaviours to actors
  *
  */
 
+/* TODO:
+ *  o Document 
+ *  o Add props
+ *  o Optimise
+ */
+
 #include "config.h"
 
 #include "clutter-actor.h"
@@ -341,6 +347,7 @@ clutter_path_behavior_get_knot (ClutterBehaviourPath  *behave,
                                guint                  index)
 {
   /* FIXME: implement */
+  return NULL;
 }
 
 void
@@ -397,7 +404,7 @@ clutter_behaviour_opacity_frame_foreach (ClutterActor            *actor,
 }
 
 static void
-clutter_behaviour_alpha_notify (ClutterBehaviour *behave)
+clutter_behaviour_opacity_alpha_notify (ClutterBehaviour *behave)
 {
   clutter_behaviour_actors_foreach 
                      (behave,
@@ -439,7 +446,7 @@ clutter_behaviour_opacity_class_init (ClutterBehaviourOpacityClass *klass)
 
   behave_class = (ClutterBehaviourClass*) klass;
 
-  behave_class->alpha_notify = clutter_behaviour_alpha_notify;
+  behave_class->alpha_notify = clutter_behaviour_opacity_alpha_notify;
 
   g_type_class_add_private (object_class, sizeof (ClutterBehaviourOpacityPrivate));
 }
@@ -469,3 +476,156 @@ clutter_behaviour_opacity_new (ClutterAlpha *alpha,
   return CLUTTER_BEHAVIOUR(behave);
 }
 
+/*
+ * ====================== Scale ============================
+ */
+
+G_DEFINE_TYPE (ClutterBehaviourScale,   \
+               clutter_behaviour_scale, \
+              CLUTTER_TYPE_BEHAVIOUR);
+
+struct ClutterBehaviourScalePrivate
+{
+  ClutterFixed   scale_begin;
+  ClutterFixed   scale_end;
+  ClutterGravity gravity;
+};
+
+#define CLUTTER_BEHAVIOUR_SCALE_GET_PRIVATE(obj)    \
+              (G_TYPE_INSTANCE_GET_PRIVATE ((obj),    \
+               CLUTTER_TYPE_BEHAVIOUR_SCALE,        \
+               ClutterBehaviourScalePrivate))
+
+static void
+clutter_behaviour_scale_frame_foreach (ClutterActor            *actor,
+                                        ClutterBehaviourScale *behave)
+{
+  ClutterFixed                    scale, factor;
+  guint32                         alpha;
+  ClutterBehaviourScalePrivate   *priv;
+  ClutterBehaviour               *_behave;
+  gint                            sw, sh, w, h;
+
+  priv = CLUTTER_BEHAVIOUR_SCALE_GET_PRIVATE (behave);
+  _behave = CLUTTER_BEHAVIOUR (behave);
+
+  alpha = clutter_alpha_get_alpha (clutter_behaviour_get_alpha (_behave));
+
+  /* FIXME: use all fixed if possible
+  factor = CLUTTER_FIXED_DIV(CLUTTER_INT_TO_FIXED(alpha/2),
+                            CLUTTER_INT_TO_FIXED(CLUTTER_ALPHA_MAX_ALPHA/2));
+  */
+
+  factor = CLUTTER_FLOAT_TO_FIXED((double) alpha / CLUTTER_ALPHA_MAX_ALPHA);
+
+  scale = CLUTTER_FIXED_MUL(factor, (priv->scale_end - priv->scale_begin));
+
+  scale += priv->scale_begin;
+
+  clutter_actor_set_scalex (actor, scale, scale);
+
+  if (priv->gravity == CLUTTER_GRAVITY_NONE 
+      || priv->gravity == CLUTTER_GRAVITY_NORTH_WEST)
+    return;
+
+  clutter_actor_get_abs_size (actor, (guint*)&sw, (guint*)&sh);
+  clutter_actor_get_size (actor, (guint*)&w, (guint*)&h);
+
+  switch (priv->gravity)
+    {
+    case CLUTTER_GRAVITY_NORTH:
+      break;
+    case CLUTTER_GRAVITY_NORTH_EAST:
+      break;
+    case CLUTTER_GRAVITY_EAST:
+      break;
+    case CLUTTER_GRAVITY_SOUTH_EAST:
+      break;
+    case CLUTTER_GRAVITY_SOUTH:
+      break;
+    case CLUTTER_GRAVITY_SOUTH_WEST:
+      break;
+    case CLUTTER_GRAVITY_WEST:
+      break;
+    case CLUTTER_GRAVITY_CENTER:
+      printf("%i vs %i\n", sw, w);
+      clutter_actor_move_by (actor, sw - w, sh - h);
+    default:
+      break;
+    }
+}
+
+static void
+clutter_behaviour_scale_alpha_notify (ClutterBehaviour *behave)
+{
+  clutter_behaviour_actors_foreach 
+                     (behave,
+                     (GFunc)clutter_behaviour_scale_frame_foreach,
+                     CLUTTER_BEHAVIOUR_SCALE(behave));
+}
+
+static void 
+clutter_behaviour_scale_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (clutter_behaviour_scale_parent_class)->dispose (object);
+}
+
+static void 
+clutter_behaviour_scale_finalize (GObject *object)
+{
+  ClutterBehaviourScale *self = CLUTTER_BEHAVIOUR_SCALE(object); 
+
+  if (self->priv)
+    {
+      g_free(self->priv);
+      self->priv = NULL;
+    }
+
+  G_OBJECT_CLASS (clutter_behaviour_scale_parent_class)->finalize (object);
+}
+
+
+static void
+clutter_behaviour_scale_class_init (ClutterBehaviourScaleClass *klass)
+{
+  GObjectClass          *object_class;
+  ClutterBehaviourClass *behave_class;
+
+  object_class = (GObjectClass*) klass;
+
+  object_class->finalize     = clutter_behaviour_scale_finalize;
+  object_class->dispose      = clutter_behaviour_scale_dispose;
+
+  behave_class = (ClutterBehaviourClass*) klass;
+
+  behave_class->alpha_notify = clutter_behaviour_scale_alpha_notify;
+
+  g_type_class_add_private (object_class, sizeof (ClutterBehaviourScalePrivate));
+}
+
+static void
+clutter_behaviour_scale_init (ClutterBehaviourScale *self)
+{
+  ClutterBehaviourScalePrivate *priv;
+
+  self->priv = priv = CLUTTER_BEHAVIOUR_SCALE_GET_PRIVATE (self);
+}
+
+ClutterBehaviour*
+clutter_behaviour_scale_new (ClutterAlpha  *alpha,
+                            double         scale_begin,
+                            double         scale_end,
+                            ClutterGravity gravity)
+{
+  ClutterBehaviourScale *behave;
+
+  behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR_SCALE, 
+                         "alpha", alpha,
+                        NULL);
+
+  behave->priv->scale_begin = CLUTTER_FLOAT_TO_FIXED (scale_begin);
+  behave->priv->scale_end   = CLUTTER_FLOAT_TO_FIXED (scale_end);
+  behave->priv->gravity     = gravity;
+
+  return CLUTTER_BEHAVIOUR(behave);
+}
index f7d2857..347be13 100644 (file)
@@ -80,7 +80,7 @@ clutter_path_behavior_append_knots (ClutterBehaviourPath  *pathb,
                                    const ClutterKnot     *first_knot,
                                    ...);
 
-/* opacity */
+/* ============================ opacity ======================== */
 
 #define CLUTTER_TYPE_BEHAVIOUR_OPACITY clutter_behaviour_opacity_get_type()
 
@@ -126,6 +126,67 @@ clutter_behaviour_opacity_new (ClutterAlpha *alpha,
                               guint8        opacity_start,
                               guint8        opacity_end);
 
+/* ============================ scale ======================== */
+
+#define CLUTTER_TYPE_BEHAVIOUR_SCALE clutter_behaviour_scale_get_type()
+
+#define CLUTTER_BEHAVIOUR_SCALE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+  CLUTTER_TYPE_BEHAVIOUR_SCALE, ClutterBehaviourScale))
+
+#define CLUTTER_BEHAVIOUR_SCALE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+  CLUTTER_TYPE_BEHAVIOUR_SCALE, ClutterBehaviourScaleClass))
+
+#define CLUTTER_IS_BEHAVIOUR_SCALE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+  CLUTTER_TYPE_BEHAVIOUR_SCALE))
+
+#define CLUTTER_IS_BEHAVIOUR_SCALE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+  CLUTTER_TYPE_BEHAVIOUR_SCALE))
+
+#define CLUTTER_BEHAVIOUR_SCALE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+  CLUTTER_TYPE_BEHAVIOUR_SCALE, ClutterBehaviourScaleClass))
+
+typedef struct _ClutterBehaviourScale       ClutterBehaviourScale;
+typedef struct ClutterBehaviourScalePrivate ClutterBehaviourScalePrivate;
+typedef struct _ClutterBehaviourScaleClass  ClutterBehaviourScaleClass;
+struct _ClutterBehaviourScale
+{
+  ClutterBehaviour             parent;
+  ClutterBehaviourScalePrivate *priv;
+};
+
+struct _ClutterBehaviourScaleClass
+{
+  ClutterBehaviourClass   parent_class;
+};
+
+typedef enum {
+  CLUTTER_GRAVITY_NONE = 0,
+  CLUTTER_GRAVITY_NORTH,
+  CLUTTER_GRAVITY_NORTH_EAST,
+  CLUTTER_GRAVITY_EAST,
+  CLUTTER_GRAVITY_SOUTH_EAST,
+  CLUTTER_GRAVITY_SOUTH,
+  CLUTTER_GRAVITY_SOUTH_WEST,
+  CLUTTER_GRAVITY_WEST,
+  CLUTTER_GRAVITY_NORTH_WEST,
+  CLUTTER_GRAVITY_CENTER
+} ClutterGravity;
+
+GType clutter_behaviour_scale_get_type (void);
+
+ClutterBehaviour*
+clutter_behaviour_scale_new (ClutterAlpha  *alpha,
+                            double         scale_begin,
+                            double         scale_end,
+                            ClutterGravity gravity);
+
+
 G_END_DECLS
 
 #endif
index 4ff4c04..fe395ed 100644 (file)
  */
 
 #include "config.h"
+#include "clutter-main.h"
 #include "clutter-feature.h"
-#include "string.h"
 
-static ClutterFeatureFlags __features = -1;
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+
+ #include <dlfcn.h>
+
+typedef void (*FuncPtr) (void);
+typedef int (*GLXGetVideoSyncProc)  (unsigned int *count);
+typedef int (*GLXWaitVideoSyncProc) (int           divisor,
+                                    int          remainder,
+                                    unsigned int *count);
+typedef FuncPtr (*GLXGetProcAddressProc) (const guint8 *procName);
+
+typedef struct ClutterFeatureFuncs
+{
+  GLXGetVideoSyncProc  get_video_sync;
+  GLXWaitVideoSyncProc wait_video_sync;
+
+} ClutterFeatureFuncs;
+
+typedef enum ClutterVBlankType
+{
+  CLUTTER_VBLANK_NONE = 0,
+  CLUTTER_VBLANK_GLX,
+  CLUTTER_VBLANK_DRI
+
+} ClutterVBlankType;
+
+typedef struct ClutterFeatures
+{
+  ClutterFeatureFlags flags;
+  ClutterFeatureFuncs funcs;
+  gint                dri_fd;
+  ClutterVBlankType   vblank_type;
+
+} ClutterFeatures;
+
+static ClutterFeatures* __features = NULL;
+
+/* #ifdef linux */
+#define DRM_VBLANK_RELATIVE 0x1;
+
+struct drm_wait_vblank_request {
+    int           type;
+    unsigned int  sequence;
+    unsigned long signal;
+};
+
+struct drm_wait_vblank_reply {
+    int          type;
+    unsigned int sequence;
+    long         tval_sec;
+    long         tval_usec;
+};
+
+typedef union drm_wait_vblank {
+    struct drm_wait_vblank_request request;
+    struct drm_wait_vblank_reply reply;
+} drm_wait_vblank_t;
+
+#define DRM_IOCTL_BASE                  'd'
+#define DRM_IOWR(nr,type)               _IOWR(DRM_IOCTL_BASE,nr,type)
+#define DRM_IOCTL_WAIT_VBLANK           DRM_IOWR(0x3a, drm_wait_vblank_t)
+
+static int drm_wait_vblank(int fd, drm_wait_vblank_t *vbl)
+{
+    int ret, rc;
+
+    do 
+      {
+       ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
+       vbl->request.type &= ~DRM_VBLANK_RELATIVE;
+       rc = errno;
+      } 
+    while (ret && rc == EINTR);
+    
+    return rc;
+}
+
+/* #endif */
+
 
 /* Note must be called after context created */
 static gboolean 
-check_gl_extension (const gchar *name)
+check_gl_extension (const gchar *name,  const gchar *ext)
 {
-  const gchar *ext;
   gchar       *end;
   gint         name_len, n;
 
-  ext = (const gchar*)glGetString(GL_EXTENSIONS);
-
   if (name == NULL || ext == NULL)
     return FALSE;
 
@@ -65,20 +146,117 @@ check_gl_extension (const gchar *name)
   return FALSE;
 }
 
+static FuncPtr
+get_proc_address (const gchar *name)
+{
+  static GLXGetProcAddressProc get_proc_func = NULL;
+  static void                 *dlhand = NULL;
+
+  if (get_proc_func == NULL && dlhand == NULL)
+    {
+      dlhand = dlopen (NULL, RTLD_LAZY);
+
+      if (dlhand)
+       {
+         dlerror ();
+         get_proc_func 
+           = (GLXGetProcAddressProc) dlsym (dlhand, "glXGetProcAddress");
+         if (dlerror () != NULL)
+           get_proc_func 
+             = (GLXGetProcAddressProc) dlsym (dlhand, "glXGetProcAddressARB");
+         if (dlerror () != NULL)
+           {
+             get_proc_func = NULL;
+             g_warning 
+               ("failed to bind GLXGetProcAddress or GLXGetProcAddressARB");
+           }
+       }
+    }
+
+  if (get_proc_func)
+    return get_proc_func ((unsigned char*)name);
+
+  return NULL;
+}
+
+
+static gboolean
+check_vblank_env (const char *name)
+{
+  const char *val;
+
+  val = getenv("CLUTTER_VBLANK");
+
+  if (val && !strcasecmp(val, name))
+    return TRUE;
+
+  return FALSE;
+}
+
 void
 clutter_feature_init (void)
 {
-  if (__features != -1)
+  const gchar *gl_extensions, *glx_extensions;
+
+  if (__features != NULL)
     {
       g_warning ("You should never call clutter_feature_init() "
                  "more than once.");
       return;
     }
 
-  __features = 0;
+  __features = g_new0 (ClutterFeatures, 1);
+  memset(&__features->funcs, 0, sizeof(ClutterFeatureFuncs));
+
+  gl_extensions = (const gchar*)glGetString(GL_EXTENSIONS);
+  glx_extensions = glXQueryExtensionsString (clutter_xdisplay(), 
+                                            clutter_xscreen());
+
+  if (check_gl_extension ("GL_ARB_texture_rectangle", gl_extensions))
+    __features->flags |= CLUTTER_FEATURE_TEXTURE_RECTANGLE;
+
+  /* vblank */
 
-  if (check_gl_extension ("GL_ARB_texture_rectangle"))
-      __features |= CLUTTER_FEATURE_TEXTURE_RECTANGLE;
+  __features->vblank_type = CLUTTER_VBLANK_NONE;
+
+  if (getenv("__GL_SYNC_TO_VBLANK") || check_vblank_env("none"))
+    {
+      CLUTTER_DBG("vblank sync: disabled at user request");
+    }
+  else
+    {
+      if (!check_vblank_env("dri") 
+         && check_gl_extension ("GLX_SGI_video_sync", glx_extensions))
+       {
+         __features->funcs.get_video_sync = 
+            (GLXGetVideoSyncProc) get_proc_address ("glXGetVideoSyncSGI");
+
+         __features->funcs.wait_video_sync = 
+           (GLXWaitVideoSyncProc) get_proc_address ("glXWaitVideoSyncSGI");
+
+         if (__features->funcs.get_video_sync != NULL
+             && __features->funcs.wait_video_sync != NULL)
+           {
+             CLUTTER_DBG("vblank sync: using glx");
+             __features->vblank_type = CLUTTER_VBLANK_GLX;
+             __features->flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
+           }
+       }
+       
+      if (!(__features->flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
+       {
+         __features->dri_fd = open("/dev/dri/card0", O_RDWR);
+         if (__features->dri_fd >= 0)
+           {
+             CLUTTER_DBG("vblank sync: using dri");
+             __features->vblank_type = CLUTTER_VBLANK_DRI;
+             __features->flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
+           }
+       }
+
+      if (!(__features->flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
+       CLUTTER_DBG("vblank sync: no use-able mechanism found");
+    }
 }
 
 /**
@@ -95,7 +273,7 @@ clutter_feature_init (void)
 gboolean
 clutter_feature_available (ClutterFeatureFlags feature)
 {
-  return (__features & feature);
+  return (__features->flags & feature);
 }
 
 /**
@@ -110,5 +288,32 @@ clutter_feature_available (ClutterFeatureFlags feature)
 ClutterFeatureFlags
 clutter_feature_all (void)
 {
-  return __features;
+  return __features->flags;
+}
+
+void
+clutter_feature_wait_for_vblank (void)
+{
+  switch (__features->vblank_type)
+    {
+    case CLUTTER_VBLANK_GLX:
+      {
+       unsigned int retraceCount;
+       __features->funcs.get_video_sync(&retraceCount);
+       __features->funcs.wait_video_sync(2, 
+                                         (retraceCount+1)%2, &retraceCount); 
+      }
+      break;
+    case CLUTTER_VBLANK_DRI:
+      {
+       drm_wait_vblank_t blank;
+       blank.request.type     = DRM_VBLANK_RELATIVE;
+       blank.request.sequence = 1;
+       drm_wait_vblank (__features->dri_fd, &blank);
+      }
+      break;
+    case CLUTTER_VBLANK_NONE:
+    default:
+      break;
+    }
 }
index d934bef..faf6322 100644 (file)
@@ -41,11 +41,13 @@ G_END_DECLS
 
 typedef enum 
 {
-  CLUTTER_FEATURE_TEXTURE_RECTANGLE = (1 << 1)
+  CLUTTER_FEATURE_TEXTURE_RECTANGLE = (1 << 1),
+  CLUTTER_FEATURE_SYNC_TO_VBLANK    = (1 << 2)
 } ClutterFeatureFlags;
 
 gboolean            clutter_feature_available (ClutterFeatureFlags flags);
 ClutterFeatureFlags clutter_feature_get_all   (void);
+void                clutter_feature_wait_for_vblank ();
 
 G_END_DECLS
 
index 933397d..7db74a7 100644 (file)
@@ -289,13 +289,7 @@ clutter_redraw (void)
 
   if (clutter_stage_get_xwindow (stage))
     {
-#if 0
-      unsigned int retraceCount;
-      /* Wait for vertical retrace */
-      /* glXGetVideoSyncSGI(&retraceCount); */
-      /* glXWaitVideoSyncSGI(2, (retraceCount+1)%2, &retraceCount); */
-      glXWaitVideoSyncSGI(1, 0, &retraceCount);
-#endif
+      clutter_feature_wait_for_vblank ();
       glXSwapBuffers(ctx->xdpy, clutter_stage_get_xwindow (stage));  
     }
   else
@@ -584,6 +578,7 @@ clutter_init (int *argc, char ***argv)
 
   events_init ();
 
+
   context->is_initialized = TRUE;
 
   return 1;