summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <llandwerlin@gmail.com>2015-09-14 23:21:29 +0100
committerLionel Landwerlin <llandwerlin@gmail.com>2015-09-15 12:23:08 +0100
commit6c7f624f691415ca9ae8c1a95d41b359704d6f1b (patch)
tree5d7ab7a74343891dfb7369f5ad9e83563759135e
parentee98a5bbe8ad21519d5e368ca5b2336e5d1da880 (diff)
downloadclutter-6c7f624f691415ca9ae8c1a95d41b359704d6f1b.tar.gz
master-clock-default: prevent deadlock with GLX_INTEL_swap_event
If we call _clutter_stage_do_update() on a ClutterStage that isn't mapped/visible, no GL command will be queued, and the Mesa/DRI2 implementation of SwapBuffers will do nothing. This causes GLX_INTEL_swap_event to not be emitted by the X server because no swapping has been requested through DRI2 and it eventually leads to a deadlock situation in ClutterStageCogl because we're waiting for an event before we start the next draw cycle. This patch removes the non mapped stages from the list of stages to process. This is consistent with a previous patch for the ClutterMasterClockGdk [1]. [1] : 5733ad58e5a3989f5cb836d42a1cebf3884e7c36 https://bugzilla.gnome.org/show_bug.cgi?id=755014
-rw-r--r--clutter/clutter-master-clock-default.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/clutter/clutter-master-clock-default.c b/clutter/clutter-master-clock-default.c
index 752cc4bf6..d854d0127 100644
--- a/clutter/clutter-master-clock-default.c
+++ b/clutter/clutter-master-clock-default.c
@@ -147,8 +147,9 @@ master_clock_is_running (ClutterMasterClockDefault *master_clock)
for (l = stages; l; l = l->next)
{
- if (_clutter_stage_has_queued_events (l->data) ||
- _clutter_stage_needs_update (l->data))
+ if (clutter_actor_is_mapped (l->data) &&
+ (_clutter_stage_has_queued_events (l->data) ||
+ _clutter_stage_needs_update (l->data)))
return TRUE;
}
@@ -222,17 +223,22 @@ master_clock_list_ready_stages (ClutterMasterClockDefault *master_clock)
for (l = stages; l != NULL; l = l->next)
{
gint64 update_time = _clutter_stage_get_update_time (l->data);
-
- /* If a stage has a swap-buffers pending we don't want to draw to it
- * in case the driver may block the CPU while it waits for the next
- * backbuffer to become available.
+ /* We carefully avoid to update stages that aren't mapped, because
+ * they have nothing to render and this could cause a deadlock with
+ * some of the SwapBuffers implementations (in particular
+ * GLX_INTEL_swap_event is not emitted if nothing was rendered).
+ *
+ * Also, if a stage has a swap-buffers pending we don't want to draw
+ * to it in case the driver may block the CPU while it waits for the
+ * next backbuffer to become available.
*
* TODO: We should be able to identify if we are running triple or N
* buffered and in these cases we can still draw if there is 1 swap
* pending so we can hopefully always be ready to swap for the next
* vblank and really match the vsync frequency.
*/
- if (update_time != -1 && update_time <= master_clock->cur_tick)
+ if (clutter_actor_is_mapped (l->data) &&
+ update_time != -1 && update_time <= master_clock->cur_tick)
result = g_slist_prepend (result, g_object_ref (l->data));
}