[PATCH 4/7] drm/vmwgfx: Move screen object page flip to atomic function

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

 



From: Deepak Rawat <drawat@xxxxxxxxxx>

The dmabuf_dirty/surface_dirty in case of screen object is moved to
plane atomic update, so that page flip in atomic ioctl also works.

vmwgfx does not support DRM_MODE_PAGE_FLIP_ASYNC, so this flag is never
expected.

Signed-off-by: Deepak Rawat <drawat@xxxxxxxxxx>
Signed-off-by: Thomas Hellstrom <thellstrom@xxxxxxxxxx>
Reviewed-by: Sinclair Yeh <syeh@xxxxxxxxxx>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 114 ++++++++++++++++++++---------------
 1 file changed, 64 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 21f4019..7164724 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -316,69 +316,21 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
 				  struct drm_modeset_acquire_ctx *ctx)
 {
 	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
-	struct drm_framebuffer *old_fb = crtc->primary->fb;
-	struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb);
-	struct vmw_fence_obj *fence = NULL;
-	struct drm_vmw_rect vclips;
 	int ret;
 
 	if (!vmw_kms_crtc_flippable(dev_priv, crtc))
 		return -EINVAL;
 
-	flags &= ~DRM_MODE_PAGE_FLIP_ASYNC;
-	ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx);
+	ret = drm_atomic_helper_page_flip(crtc, new_fb, event, flags, ctx);
 	if (ret) {
 		DRM_ERROR("Page flip error %d.\n", ret);
 		return ret;
 	}
 
-	/* do a full screen dirty update */
-	vclips.x = crtc->x;
-	vclips.y = crtc->y;
-	vclips.w = crtc->mode.hdisplay;
-	vclips.h = crtc->mode.vdisplay;
-
-	if (vfb->dmabuf)
-		ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb,
-						  NULL, &vclips, 1, 1,
-						  true, &fence, crtc);
-	else
-		ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb,
-						   NULL, &vclips, NULL,
-						   0, 0, 1, 1, &fence, crtc);
-
-
-	if (ret != 0)
-		goto out_no_fence;
-	if (!fence) {
-		ret = -EINVAL;
-		goto out_no_fence;
-	}
-
-	if (event) {
-		struct drm_file *file_priv = event->base.file_priv;
-
-		ret = vmw_event_fence_action_queue(file_priv, fence,
-						   &event->base,
-						   &event->event.vbl.tv_sec,
-						   &event->event.vbl.tv_usec,
-						   true);
-	}
-
-	/*
-	 * No need to hold on to this now. The only cleanup
-	 * we need to do if we fail is unref the fence.
-	 */
-	vmw_fence_obj_unreference(&fence);
-
 	if (vmw_crtc_to_du(crtc)->is_implicit)
 		vmw_kms_update_implicit_fb(dev_priv, crtc);
 
 	return ret;
-
-out_no_fence:
-	drm_atomic_set_fb_for_plane(crtc->primary->state, old_fb);
-	return ret;
 }
 
 static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
@@ -530,9 +482,71 @@ vmw_sou_primary_plane_atomic_update(struct drm_plane *plane,
 				    struct drm_plane_state *old_state)
 {
 	struct drm_crtc *crtc = plane->state->crtc;
+	struct drm_pending_vblank_event *event = NULL;
+	struct vmw_fence_obj *fence = NULL;
+	int ret;
+
+	if (crtc && plane->state->fb) {
+		struct vmw_private *dev_priv = vmw_priv(crtc->dev);
+		struct vmw_framebuffer *vfb =
+			vmw_framebuffer_to_vfb(plane->state->fb);
+		struct drm_vmw_rect vclips;
+
+		vclips.x = crtc->x;
+		vclips.y = crtc->y;
+		vclips.w = crtc->mode.hdisplay;
+		vclips.h = crtc->mode.vdisplay;
+
+		if (vfb->dmabuf)
+			ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb, NULL,
+							  &vclips, 1, 1, true,
+							  &fence, crtc);
+		else
+			ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL,
+							   &vclips, NULL, 0, 0,
+							   1, 1, &fence, crtc);
+
+		/*
+		 * We cannot really fail this function, so if we do, then output
+		 * an error and maintain consistent atomic state.
+		 */
+		if (ret != 0)
+			DRM_ERROR("Failed to update screen.\n");
 
-	if (crtc)
 		crtc->primary->fb = plane->state->fb;
+	} else {
+		/*
+		 * When disabling a plane, CRTC and FB should always be NULL
+		 * together, otherwise it's an error.
+		 * Here primary plane is being disable so should really blank
+		 * the screen object display unit, if not already done.
+		 */
+		return;
+	}
+
+	event = crtc->state->event;
+	/*
+	 * In case of failure and other cases, vblank event will be sent in
+	 * vmw_du_crtc_atomic_flush.
+	 */
+	if (event && fence) {
+		struct drm_file *file_priv = event->base.file_priv;
+
+		ret = vmw_event_fence_action_queue(file_priv,
+						   fence,
+						   &event->base,
+						   &event->event.vbl.tv_sec,
+						   &event->event.vbl.tv_usec,
+						   true);
+
+		if (unlikely(ret != 0))
+			DRM_ERROR("Failed to queue event on fence.\n");
+		else
+			crtc->state->event = NULL;
+	}
+
+	if (fence)
+		vmw_fence_obj_unreference(&fence);
 }
 
 
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://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