In atomic_check, damage handling is not fully evaluated. Another
atomic_check helper could trigger a full modeset and thus invalidate
damage clips.

Allocation of the request/response buffers in appletbdrm depends on
correct damage information. Otherwise it might allocate incorrectly
sized buffers. Allocate the buffers in the driver's begin_fb_access
helper. It runs early during the commit when damage clipping has been
fully evaluated.

Signed-off-by: Thomas Zimmermann <[email protected]>
Acked-by: Aditya Garg <[email protected]>
---
 drivers/gpu/drm/tiny/appletbdrm.c | 50 +++++++++++++++++++------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/tiny/appletbdrm.c 
b/drivers/gpu/drm/tiny/appletbdrm.c
index cdd35af49892..65d1796252e9 100644
--- a/drivers/gpu/drm/tiny/appletbdrm.c
+++ b/drivers/gpu/drm/tiny/appletbdrm.c
@@ -315,33 +315,21 @@ static const u32 appletbdrm_primary_plane_formats[] = {
        DRM_FORMAT_XRGB8888, /* emulated */
 };
 
-static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane 
*plane,
-                                                  struct drm_atomic_commit 
*state)
+static int appletbdrm_primary_plane_helper_begin_fb_access(struct drm_plane 
*plane,
+                                                          struct 
drm_plane_state *new_plane_state)
 {
-       struct drm_plane_state *new_plane_state = 
drm_atomic_get_new_plane_state(state, plane);
-       struct drm_plane_state *old_plane_state = 
drm_atomic_get_old_plane_state(state, plane);
-       struct drm_crtc *new_crtc = new_plane_state->crtc;
-       struct drm_crtc_state *new_crtc_state = NULL;
        struct appletbdrm_plane_state *appletbdrm_state = 
to_appletbdrm_plane_state(new_plane_state);
+       size_t frames_size = 0;
        struct drm_atomic_helper_damage_iter iter;
        struct drm_rect damage;
-       size_t frames_size = 0;
        size_t request_size;
        int ret;
 
-       if (new_crtc)
-               new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
-
-       ret = drm_atomic_helper_check_plane_state(new_plane_state, 
new_crtc_state,
-                                                 DRM_PLANE_NO_SCALING,
-                                                 DRM_PLANE_NO_SCALING,
-                                                 false, false);
+       ret = drm_gem_begin_shadow_fb_access(plane, new_plane_state);
        if (ret)
                return ret;
-       else if (!new_plane_state->visible)
-               return 0;
 
-       drm_atomic_helper_damage_iter_init(&iter, old_plane_state, 
new_plane_state);
+       drm_atomic_helper_damage_iter_init(&iter, NULL, new_plane_state);
        drm_atomic_for_each_plane_damage(&iter, &damage) {
                frames_size += struct_size((struct appletbdrm_frame *)0, buf, 
rect_size(&damage));
        }
@@ -369,6 +357,29 @@ static int 
appletbdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
        return 0;
 }
 
+static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane 
*plane,
+                                                       struct 
drm_atomic_commit *state)
+{
+       struct drm_plane_state *new_plane_state = 
drm_atomic_get_new_plane_state(state, plane);
+       struct drm_crtc *new_crtc = new_plane_state->crtc;
+       struct drm_crtc_state *new_crtc_state = NULL;
+       int ret;
+
+       if (new_crtc)
+               new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
+
+       ret = drm_atomic_helper_check_plane_state(new_plane_state, 
new_crtc_state,
+                                                 DRM_PLANE_NO_SCALING,
+                                                 DRM_PLANE_NO_SCALING,
+                                                 false, false);
+       if (ret)
+               return ret;
+       else if (!new_plane_state->visible)
+               return 0;
+
+       return 0;
+}
+
 static int appletbdrm_flush_damage(struct appletbdrm_device *adev,
                                   struct drm_plane_state *old_state,
                                   struct drm_plane_state *state)
@@ -468,7 +479,7 @@ static int appletbdrm_flush_damage(struct appletbdrm_device 
*adev,
 }
 
 static void appletbdrm_primary_plane_helper_atomic_update(struct drm_plane 
*plane,
-                                                    struct drm_atomic_commit 
*old_state)
+                                                         struct 
drm_atomic_commit *old_state)
 {
        struct appletbdrm_device *adev = drm_to_adev(plane->dev);
        struct drm_device *drm = plane->dev;
@@ -552,7 +563,8 @@ static void appletbdrm_primary_plane_destroy_state(struct 
drm_plane *plane,
 }
 
 static const struct drm_plane_helper_funcs 
appletbdrm_primary_plane_helper_funcs = {
-       DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
+       .begin_fb_access = appletbdrm_primary_plane_helper_begin_fb_access,
+       .end_fb_access = drm_gem_end_shadow_fb_access,
        .atomic_check = appletbdrm_primary_plane_helper_atomic_check,
        .atomic_update = appletbdrm_primary_plane_helper_atomic_update,
        .atomic_disable = appletbdrm_primary_plane_helper_atomic_disable,
-- 
2.54.0

Reply via email to