From b676210545b3c66e391ff3ff101d520327e1cb8a Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 19 Nov 2007 16:30:56 +0000 Subject: [PATCH] 2007-11-19 Emmanuele Bassi * clutter.symbols: Update * clutter/clutter-actor.h: Rename the angle argument for set_rotationx() to avoid gtk-doc complaining * clutter/clutter-main.h: * clutter/clutter-main.c: (clutter_set_motion_events_enabled): Rename for consistency (clutter_get_motion_events_frequency), (clutter_set_motion_events_frequency): Add accessors for the default motion events deliver frequency. (clutter_do_event): Throttle down motion events delivery using the motion events frequency setting, to avoid excessive redraws. (#608) (clutter_context_get_default): Enable per-actor motion events, at least for now. * tests/test-events.c (red_button_cb): * tests/test-grab.c (green_press_cb): Update. --- ChangeLog | 24 ++++++ clutter.symbols | 10 ++- clutter/clutter-actor.h | 3 +- clutter/clutter-main.c | 149 ++++++++++++++++++++++++++++++++++--- clutter/clutter-main.h | 23 +++--- doc/reference/ChangeLog | 5 ++ doc/reference/clutter-sections.txt | 7 +- tests/test-events.c | 4 +- tests/test-grab.c | 6 +- 9 files changed, 199 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7547bf..2d9a054 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,29 @@ 2007-11-19 Emmanuele Bassi + * clutter.symbols: Update + + * clutter/clutter-actor.h: Rename the angle argument for + set_rotationx() to avoid gtk-doc complaining + + * clutter/clutter-main.h: + * clutter/clutter-main.c: + (clutter_set_motion_events_enabled): Rename for consistency + + (clutter_get_motion_events_frequency), + (clutter_set_motion_events_frequency): Add accessors for the default + motion events deliver frequency. + + (clutter_do_event): Throttle down motion events delivery using the + motion events frequency setting, to avoid excessive redraws. (#608) + + (clutter_context_get_default): Enable per-actor motion events, at + least for now. + + * tests/test-events.c (red_button_cb): + * tests/test-grab.c (green_press_cb): Update. + +2007-11-19 Emmanuele Bassi + * clutter/clutter-timeline.c (timeline_timeout_func): Do not emit the ::new-frame signal twice for the last frame. (#531) diff --git a/clutter.symbols b/clutter.symbols index b832ebb..7a5ef0d 100644 --- a/clutter.symbols +++ b/clutter.symbols @@ -354,8 +354,16 @@ clutter_threads_add_idle clutter_threads_add_idle_full clutter_threads_add_timeout clutter_threads_add_timeout_full -clutter_enable_motion_events +clutter_set_motion_events_enabled clutter_get_motion_events_enabled +clutter_set_motion_events_frequency +clutter_get_motion_events_frequency +clutter_grab_pointer +clutter_ungrab_pointer +clutter_get_pointer_grab +clutter_grab_keyboard +clutter_ungrab_keyboard +clutter_get_keyboard_grab clutter_media_get_type clutter_media_get_uri clutter_media_get_playing diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index ca1083c..e3a7a06 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -272,7 +272,6 @@ void clutter_actor_set_x (ClutterActor *sel gint x); void clutter_actor_set_y (ClutterActor *self, gint y); - void clutter_actor_set_rotation (ClutterActor *self, ClutterRotateAxis axis, gdouble angle, @@ -281,7 +280,7 @@ void clutter_actor_set_rotation (ClutterActor *sel gint z); void clutter_actor_set_rotationx (ClutterActor *self, ClutterRotateAxis axis, - ClutterFixed fixed, + ClutterFixed angle, gint x, gint y, gint z); diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index f99e913..d53384c 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -49,21 +49,21 @@ #include "cogl.h" /* main context */ -static ClutterMainContext *ClutterCntx = NULL; +static ClutterMainContext *ClutterCntx = NULL; /* main lock and locking/unlocking functions */ static GMutex *clutter_threads_mutex = NULL; static GCallback clutter_threads_lock = NULL; static GCallback clutter_threads_unlock = NULL; -static gboolean clutter_is_initialized = FALSE; -static gboolean clutter_show_fps = FALSE; -static gboolean clutter_fatal_warnings = FALSE; +static gboolean clutter_is_initialized = FALSE; +static gboolean clutter_show_fps = FALSE; +static gboolean clutter_fatal_warnings = FALSE; -static gint clutter_default_fps = 60; +static guint clutter_default_fps = 60; -static guint clutter_main_loop_level = 0; -static GSList *main_loops = NULL; +static guint clutter_main_loop_level = 0; +static GSList *main_loops = NULL; guint clutter_debug_flags = 0; /* global clutter debug flag */ @@ -175,18 +175,44 @@ clutter_redraw (void) CLUTTER_TIMESTAMP (SCHEDULER, "Redraw finish"); } +/** + * clutter_set_motion_events_enabled: + * @enable: %TRUE to enable per-actor motion events + * + * Sets whether per-actor motion events should be enabled or not (the + * default is to enable them). + * + * If @enable is %FALSE the following events will not work: + * + * ClutterActor::motion-event, unless on the + * #ClutterStage + * ClutterActor::enter-event + * ClutterActor::leave-event + * + * + * Since: 0.6 + */ void -clutter_enable_motion_events (gboolean enable) +clutter_set_motion_events_enabled (gboolean enable) { - ClutterMainContext *context = clutter_context_get_default (); + ClutterMainContext *context = clutter_context_get_default (); context->motion_events_per_actor = enable; } +/** + * clutter_get_motion_events_enabled: + * + * Gets whether the per-actor motion events are enabled. + * + * Return value: %TRUE if the motion events are enabled + * + * Since: 0.6 + */ gboolean clutter_get_motion_events_enabled (void) { - ClutterMainContext *context = clutter_context_get_default (); + ClutterMainContext *context = clutter_context_get_default (); return context->motion_events_per_actor; } @@ -668,10 +694,13 @@ clutter_context_get_default (void) ctx->backend = g_object_new (_clutter_backend_impl_get_type (), NULL); ctx->is_initialized = FALSE; + ctx->motion_events_per_actor = TRUE; + #ifdef CLUTTER_ENABLE_DEBUG ctx->timer = g_timer_new (); g_timer_start (ctx->timer); #endif + ClutterCntx = ctx; } @@ -1297,6 +1326,7 @@ clutter_do_event (ClutterEvent *event) ClutterMainContext *context; ClutterBackend *backend; ClutterActor *stage; + static gint32 motion_last_time = 0L; context = clutter_context_get_default (); backend = context->backend; @@ -1340,7 +1370,29 @@ clutter_do_event (ClutterEvent *event) break; case CLUTTER_MOTION: - if (context->motion_events_per_actor == FALSE) + { + 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 < (motion_last_time + delta) ? "yes" : "no"), + motion_last_time, + delta, + event->any.time); + + if (event->any.time < (motion_last_time + delta)) + break; + else + motion_last_time = event->any.time; + } + + if (!context->motion_events_per_actor) { /* Only stage gets motion events */ event->any.source = stage; @@ -1473,6 +1525,19 @@ clutter_base_init (void) } } +/** + * clutter_get_default_frame_rate: + * + * Retrieves the default frame rate used when creating #ClutterTimelines. + * + * This value is also used to compute the default frequency of motion + * events. + * + * Return value: the default frame rate + * + * Since: 0.6 + */ guint clutter_get_default_frame_rate (void) { @@ -1483,6 +1548,15 @@ clutter_get_default_frame_rate (void) return context->frame_rate; } +/** + * clutter_set_default_frame_rate: + * @frames_per_sec: the new default frame rate + * + * Sets the default frame rate to be used when creating #ClutterTimelines + * + * Since: 0.6 + */ void clutter_set_default_frame_rate (guint frames_per_sec) { @@ -1663,3 +1737,56 @@ 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 + * + * 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 (); + + context->motion_frequency = frequency; +} diff --git a/clutter/clutter-main.h b/clutter/clutter-main.h index a620441..dda4b94 100644 --- a/clutter/clutter-main.h +++ b/clutter/clutter-main.h @@ -100,20 +100,21 @@ guint clutter_threads_add_timeout_full (gint priority, gpointer data, GDestroyNotify notify); -void clutter_enable_motion_events (gboolean enable); -gboolean clutter_get_motion_events_enabled (void); +void clutter_set_motion_events_enabled (gboolean enable); +gboolean clutter_get_motion_events_enabled (void); +void clutter_set_motion_events_frequency (guint frequency); +guint clutter_get_motion_events_frequency (void); -guint clutter_get_default_frame_rate (void); -void clutter_set_default_frame_rate (guint frames_per_sec); +void clutter_set_default_frame_rate (guint frames_per_sec); +guint clutter_get_default_frame_rate (void); +void clutter_grab_pointer (ClutterActor *actor); +void clutter_ungrab_pointer (void); +ClutterActor * clutter_get_pointer_grab (void); -void clutter_grab_pointer (ClutterActor *actor); -void clutter_ungrab_pointer (void); -ClutterActor * clutter_get_pointer_grab (void); - -void clutter_grab_keyboard (ClutterActor *actor); -void clutter_ungrab_keyboard (void); -ClutterActor * clutter_get_keyboard_grab (void); +void clutter_grab_keyboard (ClutterActor *actor); +void clutter_ungrab_keyboard (void); +ClutterActor * clutter_get_keyboard_grab (void); G_END_DECLS diff --git a/doc/reference/ChangeLog b/doc/reference/ChangeLog index c55b5bd..ef80767 100644 --- a/doc/reference/ChangeLog +++ b/doc/reference/ChangeLog @@ -1,3 +1,8 @@ +2007-11-19 Emmanuele Bassi + + * clutter-sections.txt: Remove clutter_behaviour_bspline_append() and + add the new motion events settings API. + 2007-11-18 Emmanuele Bassi * Makefile.am: Add clutter-x11.h to the headers scanned. diff --git a/doc/reference/clutter-sections.txt b/doc/reference/clutter-sections.txt index 27c5e4e..5b77cde 100644 --- a/doc/reference/clutter-sections.txt +++ b/doc/reference/clutter-sections.txt @@ -637,7 +637,6 @@ ClutterBehaviourBsplineClass clutter_behaviour_bspline_new clutter_behaviour_bspline_append_knot clutter_behaviour_bspline_append_knots -clutter_behaviour_bspline_append clutter_behaviour_bspline_truncate clutter_behaviour_bspline_join clutter_behaviour_bspline_split @@ -890,10 +889,12 @@ clutter_get_debug_enabled clutter_get_show_fps clutter_get_timestamp clutter_get_actor_by_gid -clutter_get_default_frame_rate clutter_set_default_frame_rate +clutter_get_default_frame_rate +clutter_set_motion_events_enabled clutter_get_motion_events_enabled -clutter_enable_motion_events +clutter_set_motion_events_frequency +clutter_get_motion_events_frequency clutter_threads_set_lock_functions diff --git a/tests/test-events.c b/tests/test-events.c index 2b04277..49abd48 100644 --- a/tests/test-events.c +++ b/tests/test-events.c @@ -1,6 +1,6 @@ #include -gboolean IsFullScreen = FALSE, IsMotion = FALSE; +gboolean IsFullScreen = FALSE, IsMotion = TRUE; static void stage_state_cb (ClutterStage *stage, @@ -41,7 +41,7 @@ red_button_cb (ClutterActor *actor, else IsMotion = TRUE; - clutter_enable_motion_events (IsMotion); + clutter_set_motion_events_enabled (IsMotion); return FALSE; } diff --git a/tests/test-grab.c b/tests/test-grab.c index 515940d..d0af938 100644 --- a/tests/test-grab.c +++ b/tests/test-grab.c @@ -107,9 +107,11 @@ green_press_cb (ClutterActor *actor, ClutterEvent *event, gpointer data) { - clutter_enable_motion_events (!clutter_get_motion_events_enabled ()); + clutter_set_motion_events_enabled (!clutter_get_motion_events_enabled ()); + g_print ("per actor motion events are now %s\n", - clutter_get_motion_events_enabled ()?"enabled":"disabled"); + clutter_get_motion_events_enabled () ? "enabled" : "disabled"); + return FALSE; } -- 2.7.4