From: James Lin <[email protected]>

[Why]
dm_crtc_get_cursor_mode() only re-evaluates the required cursor mode
(native vs overlay) when a top plane changes its scale, pixel format,
enable state, or zpos/color pipeline. It does not re-evaluate when a
plane changes only its destination rectangle (crtc_x, crtc_y, crtc_w,
crtc_h) at a constant scale. A pure move/resize can create or remove a
hole under the cursor, which changes whether the native cursor is valid.
When a primary plane shrinks and no longer covers the cursor region, the
cursor mode stays NATIVE and the cursor is not rendered over the
uncovered area, so it becomes invisible there. This is caught by
igt@amdgpu/amd_cursor_overlay@non-full, where the test CRC was a constant
black value across all cursor positions instead of tracking the
reference.

[How]
In the per-plane loop of dm_crtc_get_cursor_mode(), set
consider_mode_change when any of crtc_x, crtc_y, crtc_w or crtc_h differs
between the old and new plane state, so a plane move/resize forces
re-evaluation of the cursor mode. The driver then correctly promotes the
cursor to OVERLAY mode when the primary stops covering the cursor region.

Reviewed-by: ChiaHsuan (Tom) Chung <[email protected]>
Signed-off-by: James Lin <[email protected]>
Signed-off-by: George Zhang <[email protected]>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index b97ceabe6173..d67dcaa3fa8f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6647,6 +6647,20 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device 
*adev,
                        break;
                }

+               /*
+                * A plane moving or resizing (without a scale change) changes 
how
+                * much of the CRTC it covers. This can create/remove holes 
under
+                * the cursor and thus flip the required cursor mode (native vs
+                * overlay), so the destination rect must be re-evaluated too.
+                */
+               if (old_plane_state->crtc_x != plane_state->crtc_x ||
+                   old_plane_state->crtc_y != plane_state->crtc_y ||
+                   old_plane_state->crtc_w != plane_state->crtc_w ||
+                   old_plane_state->crtc_h != plane_state->crtc_h) {
+                       consider_mode_change = true;
+                       break;
+               }
+
                if (dm_plane_color_pipeline_active(state, plane, true) !=
                    dm_plane_color_pipeline_active(state, plane, false)) {
                        consider_mode_change = true;
--
2.55.0

Reply via email to