[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