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

Kristian Høgsberg hoegsberg at gmail.com
Tue Jun 26 07:29:47 PDT 2012


On Tue, Jun 26, 2012 at 05:09:13PM +0300, Ander Conselvan de Oliveira wrote:
> 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.

Right.  We could use some kind of pending notification ref-count
mechanism to unify the finish_frame handling, but this is fine.  And
this nicely illustrates why we need the multi-buffer pageflip ioctl :)

Kristian

> ---
>  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
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list