[RFC PATCH] drm: Add plane event

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxx>
Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
---
 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@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux