mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +00:00
[timeline] Limit timelines to 1000 frames per second
Since we are using milliseconds granularity to integrate timelines with the GLib main loop, we cannot allow values of the :fps property bigger than 1000. This means validating the fps value both in the GParamSpec and the clutter_timeline_set_speed() accessor function. This should also fix floating point exceptions when trying to perform "n_frames = milliseconds / (1000 / fps)". See bug 1354: http://bugzilla.openedhand.com/show_bug.cgi?id=1354
This commit is contained in:
parent
81f642d4b7
commit
1e071ed859
@ -351,6 +351,7 @@ static void
|
|||||||
clutter_timeline_class_init (ClutterTimelineClass *klass)
|
clutter_timeline_class_init (ClutterTimelineClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
timeline_pool_init ();
|
timeline_pool_init ();
|
||||||
|
|
||||||
@ -364,42 +365,45 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
|||||||
/**
|
/**
|
||||||
* ClutterTimeline:fps:
|
* ClutterTimeline:fps:
|
||||||
*
|
*
|
||||||
* Timeline frames per second. Because of the nature of the main
|
* Number of frames per second. Because of the nature of the main
|
||||||
* loop used by Clutter this is to be considered a best approximation.
|
* loop used by Clutter, we can only accept a granularity of one
|
||||||
|
* frame per millisecond.
|
||||||
|
*
|
||||||
|
* This value is to be considered a best approximation.
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class,
|
pspec = g_param_spec_uint ("fps",
|
||||||
PROP_FPS,
|
"Frames Per Second",
|
||||||
g_param_spec_uint ("fps",
|
"Frames per second",
|
||||||
"Frames Per Second",
|
1, 1000,
|
||||||
"Timeline frames per second",
|
60,
|
||||||
1, G_MAXUINT,
|
CLUTTER_PARAM_READWRITE);
|
||||||
60,
|
g_object_class_install_property (object_class, PROP_FPS, pspec);
|
||||||
CLUTTER_PARAM_READWRITE));
|
|
||||||
/**
|
/**
|
||||||
* ClutterTimeline:num-frames:
|
* ClutterTimeline:num-frames:
|
||||||
*
|
*
|
||||||
* Total number of frames for the timeline.
|
* Total number of frames for the timeline.
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class,
|
pspec = g_param_spec_uint ("num-frames",
|
||||||
PROP_NUM_FRAMES,
|
"Total number of frames",
|
||||||
g_param_spec_uint ("num-frames",
|
"Total number of frames",
|
||||||
"Total number of frames",
|
1, G_MAXUINT,
|
||||||
"Timelines total number of frames",
|
1,
|
||||||
1, G_MAXUINT,
|
CLUTTER_PARAM_READWRITE);
|
||||||
1,
|
g_object_class_install_property (object_class, PROP_NUM_FRAMES, pspec);
|
||||||
CLUTTER_PARAM_READWRITE));
|
|
||||||
/**
|
/**
|
||||||
* ClutterTimeline:loop:
|
* ClutterTimeline:loop:
|
||||||
*
|
*
|
||||||
* Whether the timeline should automatically rewind and restart.
|
* Whether the timeline should automatically rewind and restart.
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class,
|
pspec = g_param_spec_boolean ("loop",
|
||||||
PROP_LOOP,
|
"Loop",
|
||||||
g_param_spec_boolean ("loop",
|
"Should the timeline automatically restart",
|
||||||
"Loop",
|
FALSE,
|
||||||
"Should the timeline automatically restart",
|
CLUTTER_PARAM_READWRITE);
|
||||||
FALSE,
|
g_object_class_install_property (object_class, PROP_LOOP, pspec);
|
||||||
CLUTTER_PARAM_READWRITE));
|
|
||||||
/**
|
/**
|
||||||
* ClutterTimeline:delay:
|
* ClutterTimeline:delay:
|
||||||
*
|
*
|
||||||
@ -408,14 +412,14 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
|||||||
*
|
*
|
||||||
* Since: 0.4
|
* Since: 0.4
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class,
|
pspec = g_param_spec_uint ("delay",
|
||||||
PROP_DELAY,
|
"Delay",
|
||||||
g_param_spec_uint ("delay",
|
"Delay before start",
|
||||||
"Delay",
|
0, G_MAXUINT,
|
||||||
"Delay before start",
|
0,
|
||||||
0, G_MAXUINT,
|
CLUTTER_PARAM_READWRITE);
|
||||||
0,
|
g_object_class_install_property (object_class, PROP_DELAY, pspec);
|
||||||
CLUTTER_PARAM_READWRITE));
|
|
||||||
/**
|
/**
|
||||||
* ClutterTimeline:duration:
|
* ClutterTimeline:duration:
|
||||||
*
|
*
|
||||||
@ -424,14 +428,14 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
|||||||
*
|
*
|
||||||
* Since: 0.6
|
* Since: 0.6
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class,
|
pspec = g_param_spec_uint ("duration",
|
||||||
PROP_DURATION,
|
"Duration",
|
||||||
g_param_spec_uint ("duration",
|
"Duration of the timeline in milliseconds",
|
||||||
"Duration",
|
0, G_MAXUINT,
|
||||||
"Duration of the timeline in milliseconds",
|
1000,
|
||||||
0, G_MAXUINT,
|
CLUTTER_PARAM_READWRITE);
|
||||||
1000,
|
g_object_class_install_property (object_class, PROP_DURATION, pspec);
|
||||||
CLUTTER_PARAM_READWRITE));
|
|
||||||
/**
|
/**
|
||||||
* ClutterTimeline:direction:
|
* ClutterTimeline:direction:
|
||||||
*
|
*
|
||||||
@ -440,14 +444,13 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
|||||||
*
|
*
|
||||||
* Since: 0.6
|
* Since: 0.6
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class,
|
pspec = g_param_spec_enum ("direction",
|
||||||
PROP_DIRECTION,
|
"Direction",
|
||||||
g_param_spec_enum ("direction",
|
"Direction of the timeline",
|
||||||
"Direction",
|
CLUTTER_TYPE_TIMELINE_DIRECTION,
|
||||||
"Direction of the timeline",
|
CLUTTER_TIMELINE_FORWARD,
|
||||||
CLUTTER_TYPE_TIMELINE_DIRECTION,
|
CLUTTER_PARAM_READWRITE);
|
||||||
CLUTTER_TIMELINE_FORWARD,
|
g_object_class_install_property (object_class, PROP_DIRECTION, pspec);
|
||||||
CLUTTER_PARAM_READWRITE));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterTimeline::new-frame:
|
* ClutterTimeline::new-frame:
|
||||||
@ -547,7 +550,8 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
|||||||
timeline_signals[MARKER_REACHED] =
|
timeline_signals[MARKER_REACHED] =
|
||||||
g_signal_new ("marker-reached",
|
g_signal_new ("marker-reached",
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
|
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
|
||||||
|
G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
|
||||||
G_STRUCT_OFFSET (ClutterTimelineClass, marker_reached),
|
G_STRUCT_OFFSET (ClutterTimelineClass, marker_reached),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
clutter_marshal_VOID__STRING_INT,
|
clutter_marshal_VOID__STRING_INT,
|
||||||
@ -612,7 +616,7 @@ timeline_timeout_func (gpointer data)
|
|||||||
ClutterTimeline *timeline = data;
|
ClutterTimeline *timeline = data;
|
||||||
ClutterTimelinePrivate *priv;
|
ClutterTimelinePrivate *priv;
|
||||||
GTimeVal timeval;
|
GTimeVal timeval;
|
||||||
guint n_frames;
|
guint n_frames, speed;
|
||||||
gulong msecs;
|
gulong msecs;
|
||||||
|
|
||||||
priv = timeline->priv;
|
priv = timeline->priv;
|
||||||
@ -639,7 +643,11 @@ timeline_timeout_func (gpointer data)
|
|||||||
msecs = (timeval.tv_sec - priv->prev_frame_timeval.tv_sec) * 1000;
|
msecs = (timeval.tv_sec - priv->prev_frame_timeval.tv_sec) * 1000;
|
||||||
msecs += (timeval.tv_usec - priv->prev_frame_timeval.tv_usec) / 1000;
|
msecs += (timeval.tv_usec - priv->prev_frame_timeval.tv_usec) / 1000;
|
||||||
priv->msecs_delta = msecs;
|
priv->msecs_delta = msecs;
|
||||||
n_frames = msecs / (1000 / priv->fps);
|
|
||||||
|
/* we need to avoid fps > 1000 */
|
||||||
|
speed = MAX (1000 / priv->fps, 1);
|
||||||
|
|
||||||
|
n_frames = msecs / speed;
|
||||||
if (n_frames == 0)
|
if (n_frames == 0)
|
||||||
n_frames = 1;
|
n_frames = 1;
|
||||||
|
|
||||||
@ -1089,10 +1097,11 @@ clutter_timeline_set_n_frames (ClutterTimeline *timeline,
|
|||||||
/**
|
/**
|
||||||
* clutter_timeline_set_speed:
|
* clutter_timeline_set_speed:
|
||||||
* @timeline: A #ClutterTimeline
|
* @timeline: A #ClutterTimeline
|
||||||
* @fps: New speed of timeline as frames per second
|
* @fps: New speed of timeline as frames per second,
|
||||||
|
* between 1 and 1000
|
||||||
*
|
*
|
||||||
* Set the speed in frames per second of the timeline.
|
* Set the speed in frames per second of the timeline.
|
||||||
**/
|
*/
|
||||||
void
|
void
|
||||||
clutter_timeline_set_speed (ClutterTimeline *timeline,
|
clutter_timeline_set_speed (ClutterTimeline *timeline,
|
||||||
guint fps)
|
guint fps)
|
||||||
@ -1100,7 +1109,7 @@ clutter_timeline_set_speed (ClutterTimeline *timeline,
|
|||||||
ClutterTimelinePrivate *priv;
|
ClutterTimelinePrivate *priv;
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
|
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
|
||||||
g_return_if_fail (fps > 0);
|
g_return_if_fail (fps > 0 && fps <= 1000);
|
||||||
|
|
||||||
priv = timeline->priv;
|
priv = timeline->priv;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user