drm/amd/display: Bail from dm_check_crtc_cursor if no relevant change
authorjsg <jsg@openbsd.org>
Tue, 21 Nov 2023 02:30:21 +0000 (02:30 +0000)
committerjsg <jsg@openbsd.org>
Tue, 21 Nov 2023 02:30:21 +0000 (02:30 +0000)
From Michel Daenzer
03e334565d2d67673d7405b5b4a746da0fc20f71 in linux-6.1.y/6.1.63
bc0b79ce2050aa523c38c96b6d26340a96bfbdca in mainline linux

sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index e3e1642..64a9b95 100644 (file)
@@ -9645,10 +9645,12 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
                                struct drm_crtc *crtc,
                                struct drm_crtc_state *new_crtc_state)
 {
-       struct drm_plane *cursor = crtc->cursor, *underlying;
+       struct drm_plane *cursor = crtc->cursor, *plane, *underlying;
+       struct drm_plane_state *old_plane_state, *new_plane_state;
        struct drm_plane_state *new_cursor_state, *new_underlying_state;
        int i;
        int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h;
+       bool any_relevant_change = false;
 
        /* On DCE and DCN there is no dedicated hardware cursor plane. We get a
         * cursor per pipe but it's going to inherit the scaling and
@@ -9656,6 +9658,35 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
         * blending properties match the underlying planes'.
         */
 
+       /* If no plane was enabled or changed scaling, no need to check again */
+       for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
+               int new_scale_w, new_scale_h, old_scale_w, old_scale_h;
+
+               if (!new_plane_state || !new_plane_state->fb || new_plane_state->crtc != crtc)
+                       continue;
+
+               if (!old_plane_state || !old_plane_state->fb || old_plane_state->crtc != crtc) {
+                       any_relevant_change = true;
+                       break;
+               }
+
+               if (new_plane_state->fb == old_plane_state->fb &&
+                   new_plane_state->crtc_w == old_plane_state->crtc_w &&
+                   new_plane_state->crtc_h == old_plane_state->crtc_h)
+                       continue;
+
+               dm_get_plane_scale(new_plane_state, &new_scale_w, &new_scale_h);
+               dm_get_plane_scale(old_plane_state, &old_scale_w, &old_scale_h);
+
+               if (new_scale_w != old_scale_w || new_scale_h != old_scale_h) {
+                       any_relevant_change = true;
+                       break;
+               }
+       }
+
+       if (!any_relevant_change)
+               return 0;
+
        new_cursor_state = drm_atomic_get_plane_state(state, cursor);
        if (IS_ERR(new_cursor_state))
                return PTR_ERR(new_cursor_state);