[PATCH weston 3/5] compositor-drm: Wait for vblank events before starting next frame

Ander Conselvan de Oliveira conselvan2 at gmail.com
Tue Jun 26 07:09:13 PDT 2012


Besides the fact of the frame not being done, assigning planes before
the vblank handler is called will make the state inconsistent, leading
to a crash.
---
 src/compositor-drm.c |   27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 5543462..d969d52 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -98,6 +98,9 @@ struct drm_output {
 	uint32_t connector_id;
 	drmModeCrtcPtr original_crtc;
 
+	int vblank_pending;
+	int page_flip_pending;
+
 	struct gbm_surface *surface;
 	struct gbm_bo *cursor_bo[2];
 	int current_cursor;
@@ -118,6 +121,8 @@ struct drm_sprite {
 	struct weston_surface *surface;
 	struct weston_surface *pending_surface;
 
+	struct drm_output *output;
+
 	struct drm_compositor *compositor;
 
 	struct wl_listener destroy_listener;
@@ -358,6 +363,8 @@ drm_output_repaint(struct weston_output *output_base,
 		return;
 	}
 
+	output->page_flip_pending = 1;
+
 	/*
 	 * Now, update all the sprite surfaces
 	 */
@@ -391,6 +398,9 @@ drm_output_repaint(struct weston_output *output_base,
 			weston_log("vblank event request failed: %d: %s\n",
 				ret, strerror(errno));
 		}
+
+		s->output = output;
+		output->vblank_pending = 1;
 	}
 
 	return;
@@ -402,6 +412,10 @@ vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
 {
 	struct drm_sprite *s = (struct drm_sprite *)data;
 	struct drm_compositor *c = s->compositor;
+	struct drm_output *output = s->output;
+	uint32_t msecs;
+
+	output->vblank_pending = 0;
 
 	if (s->surface) {
 		weston_buffer_post_release(s->surface->buffer);
@@ -420,6 +434,11 @@ vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
 		s->fb_id = s->pending_fb_id;
 		s->pending_fb_id = 0;
 	}
+
+	if (!output->page_flip_pending) {
+		msecs = sec * 1000 + usec / 1000;
+		weston_output_finish_frame(&output->base, msecs);
+	}
 }
 
 static void
@@ -429,6 +448,8 @@ page_flip_handler(int fd, unsigned int frame,
 	struct drm_output *output = (struct drm_output *) data;
 	uint32_t msecs;
 
+	output->page_flip_pending = 0;
+
 	if (output->current) {
 		if (output->current->is_client_buffer)
 			gbm_bo_destroy(output->current->bo);
@@ -440,8 +461,10 @@ page_flip_handler(int fd, unsigned int frame,
 	output->current = output->next;
 	output->next = NULL;
 
-	msecs = sec * 1000 + usec / 1000;
-	weston_output_finish_frame(&output->base, msecs);
+	if (!output->vblank_pending) {
+		msecs = sec * 1000 + usec / 1000;
+		weston_output_finish_frame(&output->base, msecs);
+	}
 }
 
 static int
-- 
1.7.9.5



More information about the wayland-devel mailing list