compositor: Repaint immediately after pageflip finishes
diff --git a/compositor/compositor.c b/compositor/compositor.c
index f51973e..b1358fe 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -630,39 +630,6 @@
 }
 
 WL_EXPORT void
-wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
-{
-	struct wlsc_compositor *compositor = output->compositor;
-	struct wlsc_animation *animation, *next;
-
-	wlsc_buffer_post_release(output->scanout_buffer);
-	output->scanout_buffer = NULL;
-
-	output->finished = 1;
-
-	wl_event_source_timer_update(compositor->timer_source, 5);
-	compositor->repaint_on_timeout = 1;
-
-	wl_list_for_each_safe(animation, next,
-			      &compositor->animation_list, link)
-		animation->frame(animation, output, msecs);
-}
-
-static void
-wlsc_output_finish_redraw(struct wlsc_output *output, int msecs)
-{
-	struct wlsc_compositor *compositor = output->compositor;
-	struct wlsc_surface *es;
-
-	wl_list_for_each(es, &compositor->surface_list, link) {
-		if (es->output == output) {
-			wl_display_post_frame(compositor->wl_display,
-					      &es->surface, msecs);
-		}
-	}
-}
-
-WL_EXPORT void
 wlsc_output_damage(struct wlsc_output *output)
 {
 	struct wlsc_compositor *compositor = output->compositor;
@@ -783,8 +750,6 @@
 			wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev,
 				       &output->scanout_buffer_destroy_listener.link);
 
-			wlsc_output_finish_redraw(output,
-						  wlsc_compositor_get_time());
 			return;
 		}
 	}
@@ -823,56 +788,69 @@
 
 	if (ec->fade.spring.current > 0.001)
 		fade_output(output, ec->fade.spring.current, &total_damage);
-
-	wlsc_output_finish_redraw(output, wlsc_compositor_get_time());
 }
 
-static int
-repaint(void *data)
+static void
+repaint(void *data, int msecs)
 {
-	struct wlsc_compositor *ec = data;
-	struct wlsc_output *output;
-	int repainted_all_outputs = 1;
+	struct wlsc_output *output = data;
+	struct wlsc_compositor *compositor = output->compositor;
+	struct wlsc_surface *es;
+	struct wlsc_animation *animation, *next;
 
-	wl_list_for_each(output, &ec->output_list, link) {
-		if (!output->repaint_needed)
-			continue;
+	wlsc_output_repaint(output);
+	output->repaint_needed = 0;
+	output->repaint_scheduled = 1;
+	output->present(output);
 
-		if (!output->finished) {
-			repainted_all_outputs = 0;
-			continue;
+	/* FIXME: Keep the surfaces in an per-output list. */
+	wl_list_for_each(es, &compositor->surface_list, link) {
+		if (es->output == output) {
+			wl_display_post_frame(compositor->wl_display,
+					      &es->surface, msecs);
 		}
-
-		wlsc_output_repaint(output);
-		output->finished = 0;
-		output->repaint_needed = 0;
-		output->present(output);
 	}
 
-	if (repainted_all_outputs)
-		ec->repaint_on_timeout = 0;
-	else
-		wl_event_source_timer_update(ec->timer_source, 1);
+	wl_list_for_each_safe(animation, next,
+			      &compositor->animation_list, link)
+		animation->frame(animation, output, msecs);
+}
 
-	return 1;
+static void
+idle_repaint(void *data)
+{
+	repaint(data, wlsc_compositor_get_time());
+}
+
+WL_EXPORT void
+wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
+{
+	wlsc_buffer_post_release(output->scanout_buffer);
+	output->scanout_buffer = NULL;
+	output->repaint_scheduled = 0;
+
+	if (output->repaint_needed)
+		repaint(output, msecs);
 }
 
 WL_EXPORT void
 wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
 {
 	struct wlsc_output *output;
+	struct wl_event_loop *loop;
 
 	if (compositor->state == WLSC_COMPOSITOR_SLEEPING)
 		return;
 
-	wl_list_for_each(output, &compositor->output_list, link)
+	loop = wl_display_get_event_loop(compositor->wl_display);
+	wl_list_for_each(output, &compositor->output_list, link) {
 		output->repaint_needed = 1;
+		if (output->repaint_scheduled)
+			continue;
 
-	if (compositor->repaint_on_timeout)
-		return;
-
-	wl_event_source_timer_update(compositor->timer_source, 1);
-	compositor->repaint_on_timeout = 1;
+		wl_event_loop_add_idle(loop, idle_repaint, output);
+		output->repaint_scheduled = 1;
+	}
 }
 
 WL_EXPORT void
@@ -1727,7 +1705,6 @@
 		background_create(output, option_background);
 
 	output->flags = flags;
-	output->finished = 1;
 	wlsc_output_move(output, x, y);
 
 	output->scanout_buffer_destroy_listener.func =
@@ -1863,7 +1840,6 @@
 	ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
 	wl_event_source_timer_update(ec->idle_source, option_idle_time * 1000);
 
-	ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec);
 	pixman_region32_init(&ec->damage_region);
 	wlsc_compositor_schedule_repaint(ec);
 
diff --git a/compositor/compositor.h b/compositor/compositor.h
index 4f03062..5a2e7d8 100644
--- a/compositor/compositor.h
+++ b/compositor/compositor.h
@@ -70,7 +70,7 @@
 	pixman_region32_t previous_damage_region;
 	uint32_t flags;
 	int repaint_needed;
-	int finished;
+	int repaint_scheduled;
 
 	char *make, *model;
 	uint32_t subpixel;
@@ -190,8 +190,6 @@
 	uint32_t idle_inhibit;
 
 	/* Repaint state. */
-	struct wl_event_source *timer_source;
-	int repaint_on_timeout;
 	struct timespec previous_swap;
 	pixman_region32_t damage_region;
 	struct wl_array vertices, indices;