compositor(-drm): Pageflip to fullscreen surfaces
diff --git a/compositor/compositor-drm.c b/compositor/compositor-drm.c
index 10ba65a..7527023 100644
--- a/compositor/compositor-drm.c
+++ b/compositor/compositor-drm.c
@@ -63,6 +63,9 @@
 	uint32_t fb_id[2];
 	EGLImageKHR image[2];
 	uint32_t current;	
+
+	uint32_t fs_surf_fb_id;
+	uint32_t pending_fs_surf_fb_id;
 };
 
 static int
@@ -87,6 +90,8 @@
 	struct drm_output *output = (struct drm_output *) output_base;
 	struct drm_compositor *c =
 		(struct drm_compositor *) output->base.compositor;
+	int ret;
+	uint32_t fb_id = 0;
 
 	if (drm_output_prepare_render(&output->base))
 		return -1;
@@ -94,8 +99,29 @@
 
 	output->current ^= 1;
 
+	if (output->base.scanout_surface) {
+		EGLint handle, stride;
+
+		eglExportDRMImageMESA(c->base.display,
+				      output->base.scanout_surface->image,
+				      NULL, &handle, &stride);
+
+		ret = drmModeAddFB(c->drm.fd,
+				   output->base.width, output->base.height,
+				   32, 32, stride, handle,
+				   &output->fs_surf_fb_id);
+		if (ret)
+			return -1;
+
+		printf("pageflip to fullscreen buffer: %d\n", handle);
+
+		fb_id = output->fs_surf_fb_id;
+	} else {
+		fb_id = output->fb_id[output->current ^ 1];
+	}
+
 	drmModePageFlip(c->drm.fd, output->crtc_id,
-			output->fb_id[output->current ^ 1],
+			fb_id,
 			DRM_MODE_PAGE_FLIP_EVENT, output);
 
 	return 0;
@@ -105,11 +131,52 @@
 page_flip_handler(int fd, unsigned int frame,
 		  unsigned int sec, unsigned int usec, void *data)
 {
-	struct wlsc_output *output = data;
+	struct drm_output *output = (struct drm_output *) data;
+	struct drm_compositor *c =
+		(struct drm_compositor *) output->base.compositor;
 	uint32_t msecs;
 
+	if (output->pending_fs_surf_fb_id) {
+		drmModeRmFB(c->drm.fd, output->pending_fs_surf_fb_id);
+		output->pending_fs_surf_fb_id = 0;
+	}
+
+	if (output->fs_surf_fb_id) {
+		output->pending_fs_surf_fb_id = output->fs_surf_fb_id;
+		output->fs_surf_fb_id = 0;
+	}
+
 	msecs = sec * 1000 + usec / 1000;
-	wlsc_output_finish_frame(output, msecs);
+	wlsc_output_finish_frame(&output->base, msecs);
+}
+
+static int
+drm_output_image_is_scanoutable(struct wlsc_output *output_base,
+				EGLImageKHR image)
+{
+	struct drm_output *output = (struct drm_output *) output_base;
+	struct drm_compositor *c =
+		(struct drm_compositor *) output->base.compositor;
+	EGLint handle, stride;
+	int ret;
+	uint32_t fb_id = 0;
+
+	eglExportDRMImageMESA(c->base.display, image,
+			      NULL, &handle, &stride);
+
+	ret = drmModeAddFB(c->drm.fd,
+			   output->base.width, output->base.height,
+			   32, 32, stride, handle,
+			   &fb_id);
+	if (ret)
+		return 0;
+
+	/* FIXME: change interface to keep this fb_id,
+	 * to be used directly in next pageflip? */
+	if (fb_id)
+		drmModeRmFB(c->drm.fd, fb_id);
+
+	return fb_id != 0;
 }
 
 static void
@@ -285,6 +352,7 @@
 
 	output->base.prepare_render = drm_output_prepare_render;
 	output->base.present = drm_output_present;
+	output->base.image_is_scanoutable = drm_output_image_is_scanoutable;
 
 	wl_list_insert(ec->base.output_list.prev, &output->base.link);