From: Gustavo Padovan <gustavo.pado...@collabora.co.uk>

Due to the upcoming atomic modesetting feature we need to separate
some update functions into a check step that can fail and a commit
step that should, ideally, never fail.

This commit splits intel_update_plane() and its commit part can still
fail due to the fb pinning procedure.

Signed-off-by: Gustavo Padovan <gustavo.padovan at collabora.co.uk>
---
 drivers/gpu/drm/i915/intel_sprite.c | 128 ++++++++++++++++++++++++++----------
 1 file changed, 93 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 4cbe286..b1cb606 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -844,22 +844,32 @@ static bool colorkey_enabled(struct intel_plane 
*intel_plane)
        return key.flags != I915_SET_COLORKEY_NONE;
 }

+static bool get_visible(struct drm_rect *src, struct drm_rect *dst,
+                       const struct drm_rect *clip,
+                       int min_scale, int max_scale)
+{
+       int hscale, vscale;
+
+       hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
+       BUG_ON(hscale < 0);
+
+       vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
+       BUG_ON(vscale < 0);
+
+       return drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
+}
+
 static int
-intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+intel_check_sprite_plane(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_device *dev = plane->dev;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_plane *intel_plane = to_intel_plane(plane);
-       enum pipe pipe = intel_crtc->pipe;
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
        struct drm_i915_gem_object *obj = intel_fb->obj;
-       struct drm_i915_gem_object *old_obj = intel_plane->obj;
-       int ret;
-       bool primary_enabled;
        bool visible;
        int hscale, vscale;
        int max_scale, min_scale;
@@ -882,20 +892,6 @@ intel_update_plane(struct drm_plane *plane, struct 
drm_crtc *crtc,
                .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
                .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
        };
-       const struct {
-               int crtc_x, crtc_y;
-               unsigned int crtc_w, crtc_h;
-               uint32_t src_x, src_y, src_w, src_h;
-       } orig = {
-               .crtc_x = crtc_x,
-               .crtc_y = crtc_y,
-               .crtc_w = crtc_w,
-               .crtc_h = crtc_h,
-               .src_x = src_x,
-               .src_y = src_y,
-               .src_w = src_w,
-               .src_h = src_h,
-       };

        /* Don't modify another pipe's plane */
        if (intel_plane->pipe != intel_crtc->pipe) {
@@ -930,13 +926,7 @@ intel_update_plane(struct drm_plane *plane, struct 
drm_crtc *crtc,
        drm_rect_rotate(&src, fb->width << 16, fb->height << 16,
                        intel_plane->rotation);

-       hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
-       BUG_ON(hscale < 0);
-
-       vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale);
-       BUG_ON(vscale < 0);
-
-       visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale);
+       visible = get_visible(&src, &dst, &clip, max_scale, min_scale);

        crtc_x = dst.x1;
        crtc_y = dst.y1;
@@ -1027,6 +1017,54 @@ intel_update_plane(struct drm_plane *plane, struct 
drm_crtc *crtc,
                }
        }

+       return 0;
+}
+
+static int
+intel_commit_sprite_plane(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_device *dev = plane->dev;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_plane *intel_plane = to_intel_plane(plane);
+       enum pipe pipe = intel_crtc->pipe;
+       struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+       struct drm_i915_gem_object *obj = intel_fb->obj;
+       struct drm_i915_gem_object *old_obj = intel_plane->obj;
+       int ret;
+       bool primary_enabled;
+       bool visible;
+       int max_scale, min_scale;
+       struct drm_rect src = {
+               /* sample coordinates in 16.16 fixed point */
+               .x1 = src_x,
+               .x2 = src_x + src_w,
+               .y1 = src_y,
+               .y2 = src_y + src_h,
+       };
+       struct drm_rect dst = {
+               /* integer pixels */
+               .x1 = crtc_x,
+               .x2 = crtc_x + crtc_w,
+               .y1 = crtc_y,
+               .y2 = crtc_y + crtc_h,
+       };
+       const struct drm_rect clip = {
+               .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
+               .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
+       };
+
+       max_scale = intel_plane->max_downscale << 16;
+       min_scale = intel_plane->can_scale ? 1 : (1 << 16);
+
+       drm_rect_rotate(&src, fb->width << 16, fb->height << 16,
+                       intel_plane->rotation);
+
+       visible = get_visible(&src, &dst, &clip, max_scale, min_scale);
+
        dst.x1 = crtc_x;
        dst.x2 = crtc_x + crtc_w;
        dst.y1 = crtc_y;
@@ -1055,14 +1093,14 @@ intel_update_plane(struct drm_plane *plane, struct 
drm_crtc *crtc,
        if (ret)
                return ret;

-       intel_plane->crtc_x = orig.crtc_x;
-       intel_plane->crtc_y = orig.crtc_y;
-       intel_plane->crtc_w = orig.crtc_w;
-       intel_plane->crtc_h = orig.crtc_h;
-       intel_plane->src_x = orig.src_x;
-       intel_plane->src_y = orig.src_y;
-       intel_plane->src_w = orig.src_w;
-       intel_plane->src_h = orig.src_h;
+       intel_plane->crtc_x = crtc_x;
+       intel_plane->crtc_y = crtc_y;
+       intel_plane->crtc_w = crtc_w;
+       intel_plane->crtc_h = crtc_h;
+       intel_plane->src_x = src_x;
+       intel_plane->src_y = src_y;
+       intel_plane->src_w = src_w;
+       intel_plane->src_h = src_h;
        intel_plane->obj = obj;

        if (intel_crtc->active) {
@@ -1109,6 +1147,26 @@ intel_update_plane(struct drm_plane *plane, struct 
drm_crtc *crtc,
 }

 static int
+intel_update_plane(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)
+{
+       int ret;
+
+       ret = intel_check_sprite_plane(plane, crtc, fb, crtc_x, crtc_y,
+                                      crtc_w, crtc_h, src_x, src_y,
+                                      src_w, src_h);
+       if (ret)
+               return ret;
+
+       return intel_commit_sprite_plane(plane, crtc, fb, crtc_x, crtc_y,
+                                        crtc_w, crtc_h, src_x, src_y,
+                                        src_w, src_h);
+}
+
+static int
 intel_disable_plane(struct drm_plane *plane)
 {
        struct drm_device *dev = plane->dev;
-- 
1.9.3

Reply via email to