diff mbox

drm/atomic-helper: Skip vblank waits for unchanged fbs

Message ID 1416861739-15031-1-git-send-email-daniel.vetter@ffwll.ch (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Vetter Nov. 24, 2014, 8:42 p.m. UTC
Especially with legacy cursor ioctls existing userspace assumes that
you can pile up lots of updates in one go. The super-proper way to
support this would be a special commit mode which overwrites the last
update. But getting there will be quite a bit of work.

Meanwhile do what pretty much all the drivers have done for the plane
update functions: Simply skip the vblank wait for the buffer cleanup
if the buffer is the same. Since the universal cursor plane code will
not recreate framebuffers needlessly this allows us to not slow down
legacy pageflip events while someone moves the cursor around.

v2: Drop the async plane update hunk from a previous attempt at this
issue.

v3: Fix up kerneldoc.

v4: Don't oops so badly. Reported by Jasper.

Cc: Rob Clark <robdclark@gmail.com>
Cc: "Jasper St. Pierre" <jstpierre@mecheye.net>
Reviewed-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

Comments

Jasper St. Pierre Nov. 24, 2014, 9:34 p.m. UTC | #1
With the oops fix:

Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
Tested-by: Jasper St. Pierre <jstpierre@mecheye.net>

On Mon, Nov 24, 2014 at 12:42 PM, Daniel Vetter <daniel.vetter@ffwll.ch>
wrote:

> Especially with legacy cursor ioctls existing userspace assumes that
> you can pile up lots of updates in one go. The super-proper way to
> support this would be a special commit mode which overwrites the last
> update. But getting there will be quite a bit of work.
>
> Meanwhile do what pretty much all the drivers have done for the plane
> update functions: Simply skip the vblank wait for the buffer cleanup
> if the buffer is the same. Since the universal cursor plane code will
> not recreate framebuffers needlessly this allows us to not slow down
> legacy pageflip events while someone moves the cursor around.
>
> v2: Drop the async plane update hunk from a previous attempt at this
> issue.
>
> v3: Fix up kerneldoc.
>
> v4: Don't oops so badly. Reported by Jasper.
>
> Cc: Rob Clark <robdclark@gmail.com>
> Cc: "Jasper St. Pierre" <jstpierre@mecheye.net>
> Reviewed-by: Rob Clark <robdclark@gmail.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 34
> +++++++++++++++++++++++++++++++++-
>  1 file changed, 33 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c
> b/drivers/gpu/drm/drm_atomic_helper.c
> index af37f1edd3ed..0d32039d072f 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -748,6 +748,33 @@ static void wait_for_fences(struct drm_device *dev,
>         }
>  }
>
> +static bool framebuffer_changed(struct drm_device *dev,
> +                               struct drm_atomic_state *old_state,
> +                               struct drm_crtc *crtc)
> +{
> +       struct drm_plane *plane;
> +       struct drm_plane_state *old_plane_state;
> +       int nplanes = old_state->dev->mode_config.num_total_plane;
> +       int i;
> +
> +       for (i = 0; i < nplanes; i++) {
> +               plane = old_state->planes[i];
> +               old_plane_state = old_state->plane_states[i];
> +
> +               if (!plane)
> +                       continue;
> +
> +               if (plane->state->crtc != crtc &&
> +                   old_plane_state->crtc != crtc)
> +                       continue;
> +
> +               if (plane->state->fb != old_plane_state->fb)
> +                       return true;
> +       }
> +
> +       return false;
> +}
> +
>  /**
>   * drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs
>   * @dev: DRM device
> @@ -755,7 +782,9 @@ static void wait_for_fences(struct drm_device *dev,
>   *
>   * Helper to, after atomic commit, wait for vblanks on all effected
>   * crtcs (ie. before cleaning up old framebuffers using
> - * drm_atomic_helper_cleanup_planes())
> + * drm_atomic_helper_cleanup_planes()). It will only wait on crtcs where
> the
> + * framebuffers have actually changed to optimize for the legacy cursor
> and
> + * plane update use-case.
>   */
>  void
>  drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
> @@ -781,6 +810,9 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device
> *dev,
>                 if (!crtc->state->enable)
>                         continue;
>
> +               if (!framebuffer_changed(dev, old_state, crtc))
> +                       continue;
> +
>                 ret = drm_crtc_vblank_get(crtc);
>                 if (ret != 0)
>                         continue;
> --
> 2.1.1
>
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index af37f1edd3ed..0d32039d072f 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -748,6 +748,33 @@  static void wait_for_fences(struct drm_device *dev,
 	}
 }
 
+static bool framebuffer_changed(struct drm_device *dev,
+				struct drm_atomic_state *old_state,
+				struct drm_crtc *crtc)
+{
+	struct drm_plane *plane;
+	struct drm_plane_state *old_plane_state;
+	int nplanes = old_state->dev->mode_config.num_total_plane;
+	int i;
+
+	for (i = 0; i < nplanes; i++) {
+		plane = old_state->planes[i];
+		old_plane_state = old_state->plane_states[i];
+
+		if (!plane)
+			continue;
+
+		if (plane->state->crtc != crtc &&
+		    old_plane_state->crtc != crtc)
+			continue;
+
+		if (plane->state->fb != old_plane_state->fb)
+			return true;
+	}
+
+	return false;
+}
+
 /**
  * drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs
  * @dev: DRM device
@@ -755,7 +782,9 @@  static void wait_for_fences(struct drm_device *dev,
  *
  * Helper to, after atomic commit, wait for vblanks on all effected
  * crtcs (ie. before cleaning up old framebuffers using
- * drm_atomic_helper_cleanup_planes())
+ * drm_atomic_helper_cleanup_planes()). It will only wait on crtcs where the
+ * framebuffers have actually changed to optimize for the legacy cursor and
+ * plane update use-case.
  */
 void
 drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
@@ -781,6 +810,9 @@  drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
 		if (!crtc->state->enable)
 			continue;
 
+		if (!framebuffer_changed(dev, old_state, crtc))
+			continue;
+
 		ret = drm_crtc_vblank_get(crtc);
 		if (ret != 0)
 			continue;