[PATCH v3 1/2] amd/display: check cursor plane matches underlying plane

Harry Wentland harry.wentland at amd.com
Tue Oct 5 17:45:48 UTC 2021



On 2021-09-29 15:06, Simon Ser wrote:
> The current logic checks whether the cursor plane blending
> properties match the primary plane's. However that's wrong,
> because the cursor is painted on all planes underneath. If
> the cursor is over the primary plane and the cursor plane,

Do you mean "and the underlay plane" here, instead of "and
the cursor plane"?

Harry

> it's painted on both pipes.
> 
> Iterate over the CRTC planes and check their scaling match
> the cursor's.
> 
> Signed-off-by: Simon Ser <contact at emersion.fr>
> Cc: Alex Deucher <alexander.deucher at amd.com>
> Cc: Harry Wentland <hwentlan at amd.com>
> Cc: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
> Cc: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 49 +++++++++++++------
>  1 file changed, 34 insertions(+), 15 deletions(-)
> 
> 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 3c7a8f869b40..6472c0032b54 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -10505,18 +10505,18 @@ 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_state *new_cursor_state, *new_primary_state;
> -	int cursor_scale_w, cursor_scale_h, primary_scale_w, primary_scale_h;
> +	struct drm_plane *cursor = crtc->cursor, *underlying;
> +	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;
>  
>  	/* 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
>  	 * positioning from the underlying pipe. Check the cursor plane's
> -	 * blending properties match the primary plane's. */
> +	 * blending properties match the underlying planes'. */
>  
> -	new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor);
> -	new_primary_state = drm_atomic_get_new_plane_state(state, crtc->primary);
> -	if (!new_cursor_state || !new_primary_state ||
> -	    !new_cursor_state->fb || !new_primary_state->fb) {
> +	new_cursor_state = drm_atomic_get_new_plane_state(state, cursor);
> +	if (!new_cursor_state || !new_cursor_state->fb) {
>  		return 0;
>  	}
>  
> @@ -10525,15 +10525,34 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
>  	cursor_scale_h = new_cursor_state->crtc_h * 1000 /
>  			 (new_cursor_state->src_h >> 16);
>  
> -	primary_scale_w = new_primary_state->crtc_w * 1000 /
> -			 (new_primary_state->src_w >> 16);
> -	primary_scale_h = new_primary_state->crtc_h * 1000 /
> -			 (new_primary_state->src_h >> 16);
> +	for_each_new_plane_in_state_reverse(state, underlying, new_underlying_state, i) {
> +		/* Narrow down to non-cursor planes on the same CRTC as the cursor */
> +		if (new_underlying_state->crtc != crtc || underlying == crtc->cursor)
> +			continue;
>  
> -	if (cursor_scale_w != primary_scale_w ||
> -	    cursor_scale_h != primary_scale_h) {
> -		drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match primary plane\n");
> -		return -EINVAL;
> +		/* Ignore disabled planes */
> +		if (!new_underlying_state->fb)
> +			continue;
> +
> +		underlying_scale_w = new_underlying_state->crtc_w * 1000 /
> +				     (new_underlying_state->src_w >> 16);
> +		underlying_scale_h = new_underlying_state->crtc_h * 1000 /
> +				     (new_underlying_state->src_h >> 16);
> +
> +		if (cursor_scale_w != underlying_scale_w ||
> +		    cursor_scale_h != underlying_scale_h) {
> +			drm_dbg_atomic(crtc->dev,
> +				       "Cursor [PLANE:%d:%s] scaling doesn't match underlying [PLANE:%d:%s]\n",
> +				       cursor->base.id, cursor->name, underlying->base.id, underlying->name);
> +			return -EINVAL;
> +		}
> +
> +		/* If this plane covers the whole CRTC, no need to check planes underneath */
> +		if (new_underlying_state->crtc_x <= 0 &&
> +		    new_underlying_state->crtc_y <= 0 &&
> +		    new_underlying_state->crtc_x + new_underlying_state->crtc_w >= new_crtc_state->mode.hdisplay &&
> +		    new_underlying_state->crtc_y + new_underlying_state->crtc_h >= new_crtc_state->mode.vdisplay)
> +			break;
>  	}
>  
>  	return 0;
> 



More information about the amd-gfx mailing list