From: Gustavo Padovan <gustavo.pado...@collabora.com>

Add support to async updates of cursors by using the new atomic
interface for that. Basically what this commit does is do what
intel_legacy_cursor_update() did but through atomic.

v2: move fb setting to core and use new state (Eric Anholt)

Cc: Daniel Vetter <daniel.vet...@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.pado...@collabora.com>
---
 drivers/gpu/drm/i915/intel_atomic_plane.c |  52 +++++++++++
 drivers/gpu/drm/i915/intel_display.c      | 147 +++++-------------------------
 2 files changed, 73 insertions(+), 126 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c 
b/drivers/gpu/drm/i915/intel_atomic_plane.c
index cfb4729..c5d0596 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -246,11 +246,63 @@ static void intel_plane_atomic_update(struct drm_plane 
*plane,
        }
 }
 
+static int intel_plane_atomic_async_check(struct drm_plane *plane,
+                                         struct drm_plane_state *state)
+{
+       struct drm_crtc *crtc = plane->state->crtc;
+       struct drm_crtc_state *crtc_state = crtc->state;
+
+       if (plane->type != DRM_PLANE_TYPE_CURSOR)
+               return -EINVAL;
+
+       /*
+        * When crtc is inactive or there is a modeset pending,
+        * wait for it to complete in the slowpath
+        */
+       if (!crtc_state->active || to_intel_crtc_state(crtc_state)->update_pipe)
+               return -EINVAL;
+
+       /* Only changing fb should be in the fastpath.  */
+       if (!plane->state->fb != !state->fb)
+               return -EINVAL;
+
+       return 0;
+}
+
+static void intel_plane_atomic_async_update(struct drm_plane *plane,
+                                           struct drm_plane_state *new_state)
+{
+       struct intel_plane *intel_plane = to_intel_plane(plane);
+       struct drm_crtc *crtc = plane->state->crtc;
+
+       i915_gem_track_fb(intel_fb_obj(plane->state->fb),
+                         intel_fb_obj(new_state->fb),
+                         intel_plane->frontbuffer_bit);
+
+       *to_intel_plane_state(plane->state) = *to_intel_plane_state(new_state);
+       to_intel_plane_state(new_state)->vma =
+                                       to_intel_plane_state(plane->state)->vma;
+
+       plane->state->visible = new_state->visible;
+
+       if (plane->state->visible) {
+               trace_intel_update_plane(plane, to_intel_crtc(crtc));
+               intel_plane->update_plane(plane,
+                                         to_intel_crtc_state(crtc->state),
+                                         to_intel_plane_state(new_state));
+       } else {
+               trace_intel_disable_plane(plane, to_intel_crtc(crtc));
+               intel_plane->disable_plane(plane, crtc);
+       }
+}
+
 const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
        .prepare_fb = intel_prepare_plane_fb,
        .cleanup_fb = intel_cleanup_plane_fb,
        .atomic_check = intel_plane_atomic_check,
        .atomic_update = intel_plane_atomic_update,
+       .atomic_async_check = intel_plane_atomic_async_check,
+       .atomic_async_update = intel_plane_atomic_async_update,
 };
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index e217d04..c854c87 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12993,13 +12993,29 @@ static int intel_atomic_commit(struct drm_device *dev,
        int ret = 0;
 
        /*
-        * The intel_legacy_cursor_update() fast path takes care
+        * The atomic async update fast path takes care
         * of avoiding the vblank waits for simple cursor
         * movement and flips. For cursor on/off and size changes,
         * we want to perform the vblank waits so that watermark
         * updates happen during the correct frames. Gen9+ have
         * double buffered watermarks and so shouldn't need this.
         */
+       if (state->async_update) {
+               ret = mutex_lock_interruptible(&dev->struct_mutex);
+               if (ret)
+                       return ret;
+
+               ret = drm_atomic_helper_prepare_planes(dev, state);
+               mutex_unlock(&dev->struct_mutex);
+
+               drm_atomic_helper_async_commit(dev, state);
+
+               mutex_lock(&dev->struct_mutex);
+               drm_atomic_helper_cleanup_planes(dev, state);
+               mutex_unlock(&dev->struct_mutex);
+               return 0;
+       }
+
        if (INTEL_GEN(dev_priv) < 9)
                state->legacy_cursor_update = false;
 
@@ -13141,6 +13157,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
                }
        }
 
+       if (new_state->state->async_update)
+               return 0;
+
        if (!obj && !old_obj)
                return 0;
 
@@ -13360,132 +13379,8 @@ const struct drm_plane_funcs intel_plane_funcs = {
        .atomic_destroy_state = intel_plane_destroy_state,
 };
 
-static int
-intel_legacy_cursor_update(struct drm_plane *plane,
-                          struct drm_crtc *crtc,
-                          struct drm_framebuffer *fb,
-                          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,
-                          struct drm_modeset_acquire_ctx *ctx)
-{
-       struct drm_i915_private *dev_priv = to_i915(crtc->dev);
-       int ret;
-       struct drm_plane_state *old_plane_state, *new_plane_state;
-       struct intel_plane *intel_plane = to_intel_plane(plane);
-       struct drm_framebuffer *old_fb;
-       struct drm_crtc_state *crtc_state = crtc->state;
-       struct i915_vma *old_vma;
-
-       /*
-        * When crtc is inactive or there is a modeset pending,
-        * wait for it to complete in the slowpath
-        */
-       if (!crtc_state->active || needs_modeset(crtc_state) ||
-           to_intel_crtc_state(crtc_state)->update_pipe)
-               goto slow;
-
-       old_plane_state = plane->state;
-
-       /*
-        * If any parameters change that may affect watermarks,
-        * take the slowpath. Only changing fb or position should be
-        * in the fastpath.
-        */
-       if (old_plane_state->crtc != crtc ||
-           old_plane_state->src_w != src_w ||
-           old_plane_state->src_h != src_h ||
-           old_plane_state->crtc_w != crtc_w ||
-           old_plane_state->crtc_h != crtc_h ||
-           !old_plane_state->fb != !fb)
-               goto slow;
-
-       new_plane_state = intel_plane_duplicate_state(plane);
-       if (!new_plane_state)
-               return -ENOMEM;
-
-       drm_atomic_set_fb_for_plane(new_plane_state, fb);
-
-       new_plane_state->src_x = src_x;
-       new_plane_state->src_y = src_y;
-       new_plane_state->src_w = src_w;
-       new_plane_state->src_h = src_h;
-       new_plane_state->crtc_x = crtc_x;
-       new_plane_state->crtc_y = crtc_y;
-       new_plane_state->crtc_w = crtc_w;
-       new_plane_state->crtc_h = crtc_h;
-
-       ret = 
intel_plane_atomic_check_with_state(to_intel_crtc_state(crtc->state),
-                                                 
to_intel_plane_state(new_plane_state));
-       if (ret)
-               goto out_free;
-
-       ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex);
-       if (ret)
-               goto out_free;
-
-       if (INTEL_INFO(dev_priv)->cursor_needs_physical) {
-               int align = IS_I830(dev_priv) ? 16 * 1024 : 256;
-
-               ret = i915_gem_object_attach_phys(intel_fb_obj(fb), align);
-               if (ret) {
-                       DRM_DEBUG_KMS("failed to attach phys object\n");
-                       goto out_unlock;
-               }
-       } else {
-               struct i915_vma *vma;
-
-               vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation);
-               if (IS_ERR(vma)) {
-                       DRM_DEBUG_KMS("failed to pin object\n");
-
-                       ret = PTR_ERR(vma);
-                       goto out_unlock;
-               }
-
-               to_intel_plane_state(new_plane_state)->vma = vma;
-       }
-
-       old_fb = old_plane_state->fb;
-       old_vma = to_intel_plane_state(old_plane_state)->vma;
-
-       i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb),
-                         intel_plane->frontbuffer_bit);
-
-       /* Swap plane state */
-       new_plane_state->fence = old_plane_state->fence;
-       *to_intel_plane_state(old_plane_state) = 
*to_intel_plane_state(new_plane_state);
-       new_plane_state->fence = NULL;
-       new_plane_state->fb = old_fb;
-       to_intel_plane_state(new_plane_state)->vma = old_vma;
-
-       if (plane->state->visible) {
-               trace_intel_update_plane(plane, to_intel_crtc(crtc));
-               intel_plane->update_plane(plane,
-                                         to_intel_crtc_state(crtc->state),
-                                         to_intel_plane_state(plane->state));
-       } else {
-               trace_intel_disable_plane(plane, to_intel_crtc(crtc));
-               intel_plane->disable_plane(plane, crtc);
-       }
-
-       intel_cleanup_plane_fb(plane, new_plane_state);
-
-out_unlock:
-       mutex_unlock(&dev_priv->drm.struct_mutex);
-out_free:
-       intel_plane_destroy_state(plane, new_plane_state);
-       return ret;
-
-slow:
-       return drm_atomic_helper_update_plane(plane, crtc, fb,
-                                             crtc_x, crtc_y, crtc_w, crtc_h,
-                                             src_x, src_y, src_w, src_h, ctx);
-}
-
 static const struct drm_plane_funcs intel_cursor_plane_funcs = {
-       .update_plane = intel_legacy_cursor_update,
+       .update_plane = drm_atomic_helper_update_plane,
        .disable_plane = drm_atomic_helper_disable_plane,
        .destroy = intel_plane_destroy,
        .set_property = drm_atomic_helper_plane_set_property,
-- 
2.9.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to