[RFC PATCH] drm: Add plane event

Daniel Vetter daniel at ffwll.ch
Wed Apr 18 01:46:34 PDT 2012


On Wed, Apr 18, 2012 at 01:31:59PM +0900, Joonyoung Shim wrote:
> DRM_MODE_PLANE_EVENT is similar to DRM_MODE_PAGE_FLIP_EVENT but it is
> for a plane. The setplane ioctl (DRM_IOCTL_MODE_SETPLANE) needs to
> provide the event such as DRM_MODE_PAGE_FLIP_EVENT. The setplane ioctl
> can change the framebuffer of plane but user can't know completion of
> changing the framebuffer of plane via event. If DRM_MODE_PLANE_EVENT is
> added, we can also do pageflip of a plane.
> 
> Signed-off-by: Joonyoung Shim <jy0922.shim at samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>

If I understand the current kms api correctly, set_plane is akin to
set_base and should not generate an asynchronous flip completion event. To
do that we need a new pageflip ioctl which changes a complete set of fb +
planes + any crtc attributes that might be in an atomic fashion. At which
point we can just reuse the existing page flip event mechanism.

Yours, Daniel

> ---
>  drivers/gpu/drm/drm_crtc.c |   45 ++++++++++++++++++++++++++++++++++++++++---
>  include/drm/drm.h          |    1 +
>  include/drm/drm_crtc.h     |    3 +-
>  include/drm/drm_mode.h     |    3 ++
>  4 files changed, 47 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index d3aaeb6..4c4fa03 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1690,8 +1690,10 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
>  	struct drm_plane *plane;
>  	struct drm_crtc *crtc;
>  	struct drm_framebuffer *fb;
> +	struct drm_pending_vblank_event *e = NULL;
>  	int ret = 0;
>  	unsigned int fb_width, fb_height;
> +	unsigned long flags;
>  	int i;
>  
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
> @@ -1785,16 +1787,51 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
>  		goto out;
>  	}
>  
> +	if (plane_req->flags & DRM_MODE_PLANE_EVENT) {
> +		ret = -ENOMEM;
> +		spin_lock_irqsave(&dev->event_lock, flags);
> +		if (file_priv->event_space < sizeof e->event) {
> +			spin_unlock_irqrestore(&dev->event_lock, flags);
> +			goto out;
> +		}
> +		file_priv->event_space -= sizeof e->event;
> +		spin_unlock_irqrestore(&dev->event_lock, flags);
> +
> +		e = kzalloc(sizeof *e, GFP_KERNEL);
> +		if (e == NULL) {
> +			spin_lock_irqsave(&dev->event_lock, flags);
> +			file_priv->event_space += sizeof e->event;
> +			spin_unlock_irqrestore(&dev->event_lock, flags);
> +			goto out;
> +		}
> +
> +		e->event.base.type = DRM_EVENT_SET_PLANE_COMPLETE;
> +		e->event.base.length = sizeof e->event;
> +		e->event.user_data = plane_req->user_data;
> +		e->base.event = &e->event.base;
> +		e->base.file_priv = file_priv;
> +		e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
> +	}
> +
>  	ret = plane->funcs->update_plane(plane, crtc, fb,
>  					 plane_req->crtc_x, plane_req->crtc_y,
>  					 plane_req->crtc_w, plane_req->crtc_h,
>  					 plane_req->src_x, plane_req->src_y,
> -					 plane_req->src_w, plane_req->src_h);
> -	if (!ret) {
> -		plane->crtc = crtc;
> -		plane->fb = fb;
> +					 plane_req->src_w, plane_req->src_h,
> +					 e);
> +	if (ret) {
> +		if (plane_req->flags & DRM_MODE_PLANE_EVENT) {
> +			spin_lock_irqsave(&dev->event_lock, flags);
> +			file_priv->event_space += sizeof e->event;
> +			spin_unlock_irqrestore(&dev->event_lock, flags);
> +			kfree(e);
> +		}
> +		goto out;
>  	}
>  
> +	plane->crtc = crtc;
> +	plane->fb = fb;
> +
>  out:
>  	mutex_unlock(&dev->mode_config.mutex);
>  
> diff --git a/include/drm/drm.h b/include/drm/drm.h
> index 64ff02d..8e2d385 100644
> --- a/include/drm/drm.h
> +++ b/include/drm/drm.h
> @@ -761,6 +761,7 @@ struct drm_event {
>  
>  #define DRM_EVENT_VBLANK 0x01
>  #define DRM_EVENT_FLIP_COMPLETE 0x02
> +#define DRM_EVENT_SET_PLANE_COMPLETE 0x03
>  
>  struct drm_event_vblank {
>  	struct drm_event base;
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index e250eda..19fb9ea 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -602,7 +602,8 @@ struct drm_plane_funcs {
>  			    int crtc_x, int crtc_y,
>  			    unsigned int crtc_w, unsigned int crtc_h,
>  			    uint32_t src_x, uint32_t src_y,
> -			    uint32_t src_w, uint32_t src_h);
> +			    uint32_t src_w, uint32_t src_h,
> +			    struct drm_pending_vblank_event *event);
>  	int (*disable_plane)(struct drm_plane *plane);
>  	void (*destroy)(struct drm_plane *plane);
>  };
> diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
> index 4a0aae3..5ebdbdd 100644
> --- a/include/drm/drm_mode.h
> +++ b/include/drm/drm_mode.h
> @@ -124,6 +124,7 @@ struct drm_mode_crtc {
>  
>  #define DRM_MODE_PRESENT_TOP_FIELD	(1<<0)
>  #define DRM_MODE_PRESENT_BOTTOM_FIELD	(1<<1)
> +#define DRM_MODE_PLANE_EVENT		(1<<2)
>  
>  /* Planes blend with or override other bits on the CRTC */
>  struct drm_mode_set_plane {
> @@ -139,6 +140,8 @@ struct drm_mode_set_plane {
>  	/* Source values are 16.16 fixed point */
>  	__u32 src_x, src_y;
>  	__u32 src_h, src_w;
> +
> +	__u64 user_data;
>  };
>  
>  struct drm_mode_get_plane {
> -- 
> 1.7.5.4
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Mail: daniel at ffwll.ch
Mobile: +41 (0)79 365 57 48


More information about the dri-devel mailing list