mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 03:20:46 -05:00
2006-11-15 Matthew Allum <mallum@openedhand.com>
* 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.
This commit is contained in:
parent
3f62c72d07
commit
5ca4d3718d
@ -874,6 +874,36 @@ clutter_actor_set_position (ClutterActor *self,
|
||||
clutter_actor_request_coords (self, &box);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -25,10 +25,16 @@
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -31,21 +31,102 @@
|
||||
*/
|
||||
|
||||
#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));
|
||||
|
||||
if (check_gl_extension ("GL_ARB_texture_rectangle"))
|
||||
__features |= CLUTTER_FEATURE_TEXTURE_RECTANGLE;
|
||||
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 */
|
||||
|
||||
__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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user