diff mbox

[11/11] drm/tiled: vague attempt at waving at cursors.

Message ID 1410244096-9854-12-git-send-email-airlied@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dave Airlie Sept. 9, 2014, 6:28 a.m. UTC
From: Dave Airlie <airlied@redhat.com>

This is going to be a bit of a reference counting nightmare,

Since when we moved from one tile to the other, we need to
transfer the framebuffer over between them.

Also only universal is tackled here.

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/drm/drm_crtc.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index dd0649a0..55c9ad7 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2919,7 +2919,8 @@  out:
  */
 static int drm_mode_cursor_universal(struct drm_crtc *crtc,
 				     struct drm_mode_cursor2 *req,
-				     struct drm_file *file_priv)
+				     struct drm_file *file_priv,
+				     bool draw)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_framebuffer *fb = NULL;
@@ -2970,7 +2971,7 @@  static int drm_mode_cursor_universal(struct drm_crtc *crtc,
 		crtc_y = crtc->cursor_y;
 	}
 
-	if (fb) {
+	if (fb && draw) {
 		crtc_w = fb->width;
 		crtc_h = fb->height;
 		src_w = fb->width << 16;
@@ -2981,7 +2982,7 @@  static int drm_mode_cursor_universal(struct drm_crtc *crtc,
 	 * setplane_internal will take care of deref'ing either the old or new
 	 * framebuffer depending on success.
 	 */
-	ret = setplane_internal(crtc->cursor, crtc, fb,
+	ret = setplane_internal(crtc->cursor, crtc, draw ? fb : NULL,
 				crtc_x, crtc_y, crtc_w, crtc_h,
 				0, 0, src_w, src_h);
 
@@ -3017,8 +3018,30 @@  static int drm_mode_cursor_common(struct drm_device *dev,
 	 * If this crtc has a universal cursor plane, call that plane's update
 	 * handler rather than using legacy cursor handlers.
 	 */
-	if (crtc->cursor)
-		return drm_mode_cursor_universal(crtc, req, file_priv);
+	if (crtc->cursor) {
+		struct drm_mode_cursor2 req2;
+		struct drm_crtc *tile_crtc;
+		list_for_each_entry(tile_crtc, &crtc->tile_crtc_list, tile) {
+			req2 = *req;
+
+			/* TODO broken for > 2 tiles */
+			if (req->flags & DRM_MODE_CURSOR_MOVE) {
+				bool do_move = false;
+				if (req->x > crtc->mode.hdisplay) {
+					do_move = true;
+					req2.x = req->x - crtc->mode.hdisplay;
+				}
+				if (req->y > crtc->mode.vdisplay) {
+					do_move = true;
+					req2.y = req->y - crtc->mode.vdisplay;
+				}
+				if (do_move)
+					ret = drm_mode_cursor_universal(tile_crtc, &req2, file_priv, true);
+			} else
+				ret = drm_mode_cursor_universal(tile_crtc, &req2, file_priv, true);
+		}
+		return drm_mode_cursor_universal(crtc, req, file_priv, true);
+	}
 
 	drm_modeset_lock(&crtc->mutex, NULL);
 	if (req->flags & DRM_MODE_CURSOR_BO) {