egl: Add a way to pause the ClutterMasterClock
When VT switched away, we need to pause the ClutterMasterClock, stop processing events, and stop trying to flip. https://bugzilla.gnome.org/show_bug.cgi?id=730215
This commit is contained in:
parent
32af6a3ef4
commit
b66fec0450
@ -93,6 +93,8 @@ struct _ClutterMasterClock
|
|||||||
*/
|
*/
|
||||||
guint idle : 1;
|
guint idle : 1;
|
||||||
guint ensure_next_iteration : 1;
|
guint ensure_next_iteration : 1;
|
||||||
|
|
||||||
|
guint paused : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ClutterMasterClockClass
|
struct _ClutterMasterClockClass
|
||||||
@ -143,6 +145,9 @@ master_clock_is_running (ClutterMasterClock *master_clock)
|
|||||||
|
|
||||||
stages = clutter_stage_manager_peek_stages (stage_manager);
|
stages = clutter_stage_manager_peek_stages (stage_manager);
|
||||||
|
|
||||||
|
if (master_clock->paused)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (master_clock->timelines)
|
if (master_clock->timelines)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -636,6 +641,7 @@ clutter_master_clock_init (ClutterMasterClock *self)
|
|||||||
|
|
||||||
self->idle = FALSE;
|
self->idle = FALSE;
|
||||||
self->ensure_next_iteration = FALSE;
|
self->ensure_next_iteration = FALSE;
|
||||||
|
self->paused = FALSE;
|
||||||
|
|
||||||
#ifdef CLUTTER_ENABLE_DEBUG
|
#ifdef CLUTTER_ENABLE_DEBUG
|
||||||
self->frame_budget = G_USEC_PER_SEC / 60;
|
self->frame_budget = G_USEC_PER_SEC / 60;
|
||||||
@ -740,3 +746,12 @@ _clutter_master_clock_ensure_next_iteration (ClutterMasterClock *master_clock)
|
|||||||
|
|
||||||
master_clock->ensure_next_iteration = TRUE;
|
master_clock->ensure_next_iteration = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_master_clock_set_paused (ClutterMasterClock *master_clock,
|
||||||
|
gboolean paused)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_MASTER_CLOCK (master_clock));
|
||||||
|
|
||||||
|
master_clock->paused = !!paused;
|
||||||
|
}
|
||||||
|
@ -43,6 +43,8 @@ void _clutter_master_clock_remove_timeline (Clutter
|
|||||||
ClutterTimeline *timeline);
|
ClutterTimeline *timeline);
|
||||||
void _clutter_master_clock_start_running (ClutterMasterClock *master_clock);
|
void _clutter_master_clock_start_running (ClutterMasterClock *master_clock);
|
||||||
void _clutter_master_clock_ensure_next_iteration (ClutterMasterClock *master_clock);
|
void _clutter_master_clock_ensure_next_iteration (ClutterMasterClock *master_clock);
|
||||||
|
void _clutter_master_clock_set_paused (ClutterMasterClock *master_clock,
|
||||||
|
gboolean paused);
|
||||||
|
|
||||||
void _clutter_timeline_advance (ClutterTimeline *timeline,
|
void _clutter_timeline_advance (ClutterTimeline *timeline,
|
||||||
gint64 tick_time);
|
gint64 tick_time);
|
||||||
|
@ -204,3 +204,57 @@ clutter_egl_set_kms_fd (int fd)
|
|||||||
_kms_fd = fd;
|
_kms_fd = fd;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_egl_freeze_master_clock:
|
||||||
|
*
|
||||||
|
* Freezing the master clock makes Clutter stop processing events,
|
||||||
|
* redrawing, and advancing timelines. This is necessary when implementing
|
||||||
|
* a display server, to ensure that Clutter doesn't keep trying to page
|
||||||
|
* flip when DRM master has been dropped, e.g. when VT switched away.
|
||||||
|
*
|
||||||
|
* The master clock starts out running, so if you are VT switched away on
|
||||||
|
* startup, you need to call this immediately.
|
||||||
|
*
|
||||||
|
* If you're also using the evdev backend, make sure to also use
|
||||||
|
* clutter_evdev_release_devices() to make sure that Clutter doesn't also
|
||||||
|
* access revoked evdev devices when VT switched away.
|
||||||
|
*
|
||||||
|
* To unthaw a frozen master clock, use clutter_egl_thaw_master_clock().
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_egl_freeze_master_clock (void)
|
||||||
|
{
|
||||||
|
ClutterMasterClock *master_clock;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BACKEND_EGL_NATIVE (clutter_get_default_backend ()));
|
||||||
|
|
||||||
|
master_clock = _clutter_master_clock_get_default ();
|
||||||
|
_clutter_master_clock_set_paused (master_clock, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_egl_thaw_master_clock:
|
||||||
|
*
|
||||||
|
* Thaws a master clock that has previously been frozen with
|
||||||
|
* clutter_egl_freeze_master_clock(), and start pumping the master clock
|
||||||
|
* again at the next iteration. Note that if you're switching back to your
|
||||||
|
* own VT, you should probably also queue a stage redraw with
|
||||||
|
* clutter_stage_ensure_redraw().
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_egl_thaw_master_clock (void)
|
||||||
|
{
|
||||||
|
ClutterMasterClock *master_clock;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BACKEND_EGL_NATIVE (clutter_get_default_backend ()));
|
||||||
|
|
||||||
|
master_clock = _clutter_master_clock_get_default ();
|
||||||
|
_clutter_master_clock_set_paused (master_clock, FALSE);
|
||||||
|
|
||||||
|
_clutter_master_clock_start_running (master_clock);
|
||||||
|
}
|
||||||
|
@ -92,6 +92,11 @@ CLUTTER_AVAILABLE_IN_1_18
|
|||||||
void clutter_egl_set_kms_fd (int fd);
|
void clutter_egl_set_kms_fd (int fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CLUTTER_AVAILABLE_IN_1_20
|
||||||
|
void clutter_egl_freeze_master_clock (void);
|
||||||
|
CLUTTER_AVAILABLE_IN_1_20
|
||||||
|
void clutter_egl_thaw_master_clock (void);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_EGL_H__ */
|
#endif /* __CLUTTER_EGL_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user