[master-clock] Throttle if no redraw was performed
A flag in the master clock is now set whenever the dispatch caused an actual redraw of a stage. If this flag is not set during the prepare and check functions then it will resort to limiting the redraw attempts to the default frame rate as if vblank syncing was disabled. Otherwise if a timeline is running that does not cause the scene to change then it would busy-wait with 100% CPU until the next frame. This fix was suggested by Owen Taylor in: http://bugzilla.openedhand.com/show_bug.cgi?id=1637 Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This commit is contained in:
parent
7c08f554bc
commit
acf7722a41
@ -66,6 +66,8 @@ struct _ClutterMasterClock
|
||||
* a redraw on the stage and drive the animations
|
||||
*/
|
||||
GSource *source;
|
||||
|
||||
guint updated_stages : 1;
|
||||
};
|
||||
|
||||
struct _ClutterMasterClockClass
|
||||
@ -144,7 +146,8 @@ master_clock_next_frame_delay (ClutterMasterClock *master_clock)
|
||||
if (!master_clock_is_running (master_clock))
|
||||
return -1;
|
||||
|
||||
if (clutter_feature_available (CLUTTER_FEATURE_SYNC_TO_VBLANK))
|
||||
if (clutter_feature_available (CLUTTER_FEATURE_SYNC_TO_VBLANK) &&
|
||||
master_clock->updated_stages)
|
||||
{
|
||||
/* When we have sync-to-vblank, we count on that to throttle
|
||||
* our frame rate, and otherwise draw frames as fast as possible.
|
||||
@ -250,6 +253,8 @@ clutter_clock_dispatch (GSource *source,
|
||||
stages = clutter_stage_manager_list_stages (stage_manager);
|
||||
g_slist_foreach (stages, (GFunc)g_object_ref, NULL);
|
||||
|
||||
master_clock->updated_stages = FALSE;
|
||||
|
||||
/* Process queued events
|
||||
*/
|
||||
for (l = stages; l != NULL; l = l->next)
|
||||
@ -262,7 +267,7 @@ clutter_clock_dispatch (GSource *source,
|
||||
* is advanced.
|
||||
*/
|
||||
for (l = stages; l != NULL; l = l->next)
|
||||
_clutter_stage_do_update (l->data);
|
||||
master_clock->updated_stages |= _clutter_stage_do_update (l->data);
|
||||
|
||||
g_slist_foreach (stages, (GFunc)g_object_unref, NULL);
|
||||
g_slist_free (stages);
|
||||
@ -298,6 +303,8 @@ clutter_master_clock_init (ClutterMasterClock *self)
|
||||
source = clutter_clock_source_new (self);
|
||||
self->source = source;
|
||||
|
||||
self->updated_stages = TRUE;
|
||||
|
||||
g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW);
|
||||
g_source_set_can_recurse (source, FALSE);
|
||||
g_source_attach (source, NULL);
|
||||
|
@ -174,7 +174,7 @@ ClutterStageWindow *_clutter_stage_get_default_window (void);
|
||||
void _clutter_stage_maybe_setup_viewport (ClutterStage *stage);
|
||||
void _clutter_stage_maybe_relayout (ClutterActor *stage);
|
||||
gboolean _clutter_stage_needs_update (ClutterStage *stage);
|
||||
void _clutter_stage_do_update (ClutterStage *stage);
|
||||
gboolean _clutter_stage_do_update (ClutterStage *stage);
|
||||
|
||||
void _clutter_stage_queue_event (ClutterStage *stage,
|
||||
ClutterEvent *event);
|
||||
|
@ -486,7 +486,7 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
|
||||
*
|
||||
* Determines if _clutter_stage_do_update() needs to be called.
|
||||
*
|
||||
* Return value: %TRUE if the stages need layout or painting
|
||||
* Return value: %TRUE if the stage need layout or painting
|
||||
*/
|
||||
gboolean
|
||||
_clutter_stage_needs_update (ClutterStage *stage)
|
||||
@ -505,18 +505,20 @@ _clutter_stage_needs_update (ClutterStage *stage)
|
||||
* @stage: A #ClutterStage
|
||||
*
|
||||
* Handles per-frame layout and repaint for the stage.
|
||||
*
|
||||
* Return value: %TRUE if the stage was updated
|
||||
*/
|
||||
void
|
||||
gboolean
|
||||
_clutter_stage_do_update (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
if (!priv->redraw_pending)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
/* clutter_do_redraw() will also call maybe_relayout(), but since a relayout
|
||||
* can queue a redraw, we want to do the relayout before we clear the
|
||||
@ -539,6 +541,8 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
|
||||
CLUTTER_CONTEXT ()->redraw_count = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user