Skip to content

Commit 16e9b3e

Browse files
Rodrigo Siqueiraalexdeucher
Rodrigo Siqueira
authored andcommitted
drm/amd/display: Fix two cursor duplication when using overlay
Our driver supports overlay planes, and as expected, some userspace compositor takes advantage of these features. If the userspace is not enabling the cursor, they can use multiple planes as they please. Nevertheless, we start to have constraints when userspace tries to enable hardware cursor with various planes. Basically, we cannot draw the cursor at the same size and position on two separated pipes since it uses extra bandwidth and DML only run with one cursor. For those reasons, when we enable hardware cursor and multiple planes, our driver should accept variations like the ones described below: +-------------+ +--------------+ | +---------+ | | | | |Primary | | | Primary | | | | | | Overlay | | +---------+ | | | |Overlay | | | +-------------+ +--------------+ In this scenario, we can have the desktop UI in the overlay and some other framebuffer attached to the primary plane (e.g., video). However, userspace needs to obey some rules and avoid scenarios like the ones described below (when enabling hw cursor): +--------+ |Overlay | +-------------+ +-----+-------+ +-| |--+ | +--------+ | +--------+ | | +--------+ | | |Overlay | | |Overlay | | | | | | | | | | | | | | +--------+ | +--------+ | | | | Primary | | Primary | | Primary | +-------------+ +-------------+ +-------------+ +-------------+ +-------------+ | +--------+ | Primary | | |Overlay | | | | | | | | | +--------+ | +--------+ | | Primary | | |Overlay | | +-------------+ +-| |--+ +--------+ If the userspace violates some of the above scenarios, our driver needs to reject the commit; otherwise, we can have unexpected behavior. Since we don't have a proper driver validation for the above case, we can see some problems like a duplicate cursor in applications that use multiple planes. This commit fixes the cursor issue and others by adding adequate verification for multiple planes. Change since V1 (Harry and Sean): - Remove cursor verification from the equation. Cc: Louis Li <[email protected]> Cc: Nicholas Kazlauskas <[email protected]> Cc: Harry Wentland <[email protected]> Cc: Hersen Wu <[email protected]> Cc: Sean Paul <[email protected]> Signed-off-by: Rodrigo Siqueira <[email protected]> Reviewed-by: Harry Wentland <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent c83c4e1 commit 16e9b3e

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9870,6 +9870,53 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
98709870
}
98719871
#endif
98729872

9873+
static int validate_overlay(struct drm_atomic_state *state)
9874+
{
9875+
int i;
9876+
struct drm_plane *plane;
9877+
struct drm_plane_state *old_plane_state, *new_plane_state;
9878+
struct drm_plane_state *primary_state, *overlay_state = NULL;
9879+
9880+
/* Check if primary plane is contained inside overlay */
9881+
for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
9882+
if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
9883+
if (drm_atomic_plane_disabling(plane->state, new_plane_state))
9884+
return 0;
9885+
9886+
overlay_state = new_plane_state;
9887+
continue;
9888+
}
9889+
}
9890+
9891+
/* check if we're making changes to the overlay plane */
9892+
if (!overlay_state)
9893+
return 0;
9894+
9895+
/* check if overlay plane is enabled */
9896+
if (!overlay_state->crtc)
9897+
return 0;
9898+
9899+
/* find the primary plane for the CRTC that the overlay is enabled on */
9900+
primary_state = drm_atomic_get_plane_state(state, overlay_state->crtc->primary);
9901+
if (IS_ERR(primary_state))
9902+
return PTR_ERR(primary_state);
9903+
9904+
/* check if primary plane is enabled */
9905+
if (!primary_state->crtc)
9906+
return 0;
9907+
9908+
/* Perform the bounds check to ensure the overlay plane covers the primary */
9909+
if (primary_state->crtc_x < overlay_state->crtc_x ||
9910+
primary_state->crtc_y < overlay_state->crtc_y ||
9911+
primary_state->crtc_x + primary_state->crtc_w > overlay_state->crtc_x + overlay_state->crtc_w ||
9912+
primary_state->crtc_y + primary_state->crtc_h > overlay_state->crtc_y + overlay_state->crtc_h) {
9913+
DRM_DEBUG_ATOMIC("Overlay plane is enabled with hardware cursor but does not fully cover primary plane\n");
9914+
return -EINVAL;
9915+
}
9916+
9917+
return 0;
9918+
}
9919+
98739920
/**
98749921
* amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
98759922
* @dev: The DRM device
@@ -10044,6 +10091,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
1004410091
goto fail;
1004510092
}
1004610093

10094+
ret = validate_overlay(state);
10095+
if (ret)
10096+
goto fail;
10097+
1004710098
/* Add new/modified planes */
1004810099
for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
1004910100
ret = dm_update_plane_state(dc, state, plane,

0 commit comments

Comments
 (0)