compositor, clients: apply wl_surface.frame on commit

Apply wl_surface.frame request only on the next wl_surface.commit
according to the new protocol.

This makes it explicit, which repaint actually triggered the frame
callback, since commit schedules a repaint. Otherwise, something causing
a repaint before a commit could trigger the frame callback too early.

Ensure all demo clients send commit after wl_surface.frame. Note, that
GL apps rely on eglSwapBuffers() sending commit. In toytoolkit, it is
assumed that window_flush() always does a commit.

compositor-wayland assumes renderer->repaint_output does a commit.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
diff --git a/src/compositor.c b/src/compositor.c
index eb3e632..4dd6d27 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -266,6 +266,7 @@
 	pixman_region32_init(&surface->pending.damage);
 	pixman_region32_init(&surface->pending.opaque);
 	region_init_infinite(&surface->pending.input);
+	wl_list_init(&surface->pending.frame_callback_list);
 
 	return surface;
 }
@@ -767,6 +768,10 @@
 	if (weston_surface_is_mapped(surface))
 		weston_surface_unmap(surface);
 
+	wl_list_for_each_safe(cb, next,
+			      &surface->pending.frame_callback_list, link)
+		wl_resource_destroy(&cb->resource);
+
 	pixman_region32_fini(&surface->pending.input);
 	pixman_region32_fini(&surface->pending.opaque);
 	pixman_region32_fini(&surface->pending.damage);
@@ -990,7 +995,6 @@
 		wl_callback_send_done(&cb->resource, msecs);
 		wl_resource_destroy(&cb->resource);
 	}
-	wl_list_init(&frame_callback_list);
 
 	wl_list_for_each_safe(animation, next, &output->animation_list, link) {
 		animation->frame_counter++;
@@ -1170,14 +1174,14 @@
 	      struct wl_resource *resource, uint32_t callback)
 {
 	struct weston_frame_callback *cb;
-	struct weston_surface *es = resource->data;
+	struct weston_surface *surface = resource->data;
 
 	cb = malloc(sizeof *cb);
 	if (cb == NULL) {
 		wl_resource_post_no_memory(resource);
 		return;
 	}
-		
+
 	cb->resource.object.interface = &wl_callback_interface;
 	cb->resource.object.id = callback;
 	cb->resource.destroy = destroy_frame_callback;
@@ -1185,7 +1189,7 @@
 	cb->resource.data = cb;
 
 	wl_client_add_resource(client, &cb->resource);
-	wl_list_insert(es->frame_callback_list.prev, &cb->link);
+	wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
 }
 
 static void
@@ -1258,6 +1262,11 @@
 	pixman_region32_intersect(&surface->input,
 				  &surface->input, &surface->pending.input);
 
+	/* wl_surface.frame */
+	wl_list_insert_list(&surface->frame_callback_list,
+			    &surface->pending.frame_callback_list);
+	wl_list_init(&surface->pending.frame_callback_list);
+
 	weston_surface_schedule_repaint(surface);
 }