Compress events as part of the frame cycle
Instead of trying to guess about which motion events are extraneous, queue up all events until we process a frame. This allows us to look ahead and reliably compress consecutive sequence of motion events. clutter-main.c: Feed received events to the stage for queueing. Remove old compression code. Remove clutter_get_motion_events_frequency() clutter_set_motion_events_frequency() clutter-stage.c: Keep a queue of pending events. clutter-master-clock.c: Add processng of queued events to the clock source dispatch function. http://bugzilla.openedhand.com/show_bug.cgi?id=1637 Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This commit is contained in:

committed by
Emmanuele Bassi

parent
89a8fd7755
commit
6e69692e22
@ -2004,6 +2004,29 @@ generate_enter_leave_events (ClutterEvent *event)
|
||||
*/
|
||||
void
|
||||
clutter_do_event (ClutterEvent *event)
|
||||
{
|
||||
if (!event->any.stage)
|
||||
return;
|
||||
|
||||
/* Instead of processing events when received, we queue them up to
|
||||
* handle per-frame before animations, layout, and drawing.
|
||||
*
|
||||
* This gives us the chance to reliably compress motion events
|
||||
* because we've "looked ahead" and know all motion events that
|
||||
* will occur before drawing the frame.
|
||||
*/
|
||||
_clutter_stage_queue_event (event->any.stage, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* _clutter_process_event
|
||||
* @event: a #ClutterEvent.
|
||||
*
|
||||
* Does the actual work of processing an event that was queued earlier
|
||||
* out of clutter_do_event().
|
||||
*/
|
||||
void
|
||||
_clutter_process_event (ClutterEvent *event)
|
||||
{
|
||||
/* FIXME: This should probably be clutter_cook_event() - it would
|
||||
* take a raw event from the backend and 'cook' it so its more tasty.
|
||||
@ -2013,8 +2036,6 @@ clutter_do_event (ClutterEvent *event)
|
||||
ClutterBackend *backend;
|
||||
ClutterActor *stage;
|
||||
ClutterInputDevice *device = NULL;
|
||||
static gint32 motion_last_time = 0L;
|
||||
gint32 local_motion_time;
|
||||
|
||||
context = clutter_context_get_default ();
|
||||
backend = context->backend;
|
||||
@ -2091,52 +2112,6 @@ clutter_do_event (ClutterEvent *event)
|
||||
case CLUTTER_MOTION:
|
||||
device = event->motion.device;
|
||||
|
||||
if (device)
|
||||
local_motion_time = device->motion_last_time;
|
||||
else
|
||||
local_motion_time = motion_last_time;
|
||||
|
||||
/* avoid rate throttling for synthetic motion events or if
|
||||
* the per-actor events are disabled
|
||||
*/
|
||||
if (!(event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC) ||
|
||||
!context->motion_events_per_actor)
|
||||
{
|
||||
gint32 frame_rate, delta;
|
||||
|
||||
/* avoid issuing too many motion events, which leads to many
|
||||
* redraws in pick mode (performance penalty)
|
||||
*/
|
||||
frame_rate = clutter_get_motion_events_frequency ();
|
||||
delta = 1000 / frame_rate;
|
||||
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"skip motion event: %s (last:%d, delta:%d, time:%d)",
|
||||
(event->any.time < (local_motion_time + delta) ? "yes" : "no"),
|
||||
local_motion_time,
|
||||
delta,
|
||||
event->any.time);
|
||||
|
||||
/* we need to guard against roll-overs and the
|
||||
* case where the time is rolled backwards and
|
||||
* the backend is not ensuring a monotonic clock
|
||||
* for the events.
|
||||
*
|
||||
* see:
|
||||
* http://bugzilla.openedhand.com/show_bug.cgi?id=1130
|
||||
*/
|
||||
if (event->any.time >= local_motion_time &&
|
||||
event->any.time < (local_motion_time + delta))
|
||||
break;
|
||||
else
|
||||
local_motion_time = event->any.time;
|
||||
}
|
||||
|
||||
if (device)
|
||||
device->motion_last_time = local_motion_time;
|
||||
else
|
||||
motion_last_time = local_motion_time;
|
||||
|
||||
/* Only stage gets motion events if clutter_set_motion_events is TRUE,
|
||||
* and the event is not a synthetic event with source set.
|
||||
*/
|
||||
@ -2321,9 +2296,6 @@ clutter_base_init (void)
|
||||
* Retrieves the default frame rate used when creating #ClutterTimeline<!--
|
||||
* -->s.
|
||||
*
|
||||
* This value is also used to compute the default frequency of motion
|
||||
* events.
|
||||
*
|
||||
* Return value: the default frame rate
|
||||
*
|
||||
* Since: 0.6
|
||||
@ -2621,61 +2593,6 @@ clutter_get_keyboard_grab (void)
|
||||
return context->keyboard_grab_actor;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_motion_events_frequency:
|
||||
*
|
||||
* Retrieves the number of motion events per second that are delivered
|
||||
* to the stage.
|
||||
*
|
||||
* See clutter_set_motion_events_frequency().
|
||||
*
|
||||
* Return value: the number of motion events per second
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
guint
|
||||
clutter_get_motion_events_frequency (void)
|
||||
{
|
||||
ClutterMainContext *context = clutter_context_get_default ();
|
||||
|
||||
if (G_LIKELY (context->motion_frequency == 0))
|
||||
{
|
||||
guint frequency;
|
||||
|
||||
frequency = clutter_default_fps / 4;
|
||||
frequency = CLAMP (frequency, 20, 45);
|
||||
|
||||
return frequency;
|
||||
}
|
||||
else
|
||||
return context->motion_frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_set_motion_events_frequency:
|
||||
* @frequency: the number of motion events per second, or 0 for the
|
||||
* default value
|
||||
*
|
||||
* Sets the motion events frequency. Setting this to a non-zero value
|
||||
* will override the default setting, so it should be rarely used.
|
||||
*
|
||||
* Motion events are delivered from the default backend to the stage
|
||||
* and are used to generate the enter/leave events pair. This might lead
|
||||
* to a performance penalty due to the way the actors are identified.
|
||||
* Using this function is possible to reduce the frequency of the motion
|
||||
* events delivery to the stage.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
void
|
||||
clutter_set_motion_events_frequency (guint frequency)
|
||||
{
|
||||
ClutterMainContext *context = clutter_context_get_default ();
|
||||
|
||||
/* never allow the motion events to exceed the default frame rate */
|
||||
context->motion_frequency = CLAMP (frequency, 1, clutter_default_fps);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_clear_glyph_cache:
|
||||
*
|
||||
|
Reference in New Issue
Block a user