[PATCH v2] drm/amd/display: Fix two cursor duplication when using overlay
Harry Wentland
harry.wentland at amd.com
Wed Apr 14 13:29:30 UTC 2021
On 2021-04-13 8:06 p.m., Rodrigo Siqueira wrote:
> 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.
>
It might be good to have a brief mention that regardless of whether we
have a cursor plane we want to reject the problematic plane configs
since some userspace doesn't handle atomic check/commit rejections well
when only the cursor enablement changes.
> Change since V1 (Harry and Sean):
> - Remove cursor verification from the equation.
>
> Cc: Louis Li <Ching-shih.Li at amd.com>
> Cc: Nicholas Kazlauskas <Nicholas.Kazlauskas at amd.com>
> Cc: Harry Wentland <Harry.Wentland at amd.com>
> Cc: Hersen Wu <hersenxs.wu at amd.com>
> Cc: Sean Paul <seanpaul at chromium.org>
> Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira at amd.com>
EIther way, this patch is
Reviewed-by: Harry Wentland <harry.wentland at amd.com>
Harry
> ---
> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 51 +++++++++++++++++++
> 1 file changed, 51 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 e29cb2e956db..ac1408d52eff 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -9946,6 +9946,53 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
> }
> #endif
>
> +static int validate_overlay(struct drm_atomic_state *state)
> +{
> + int i;
> + struct drm_plane *plane;
> + struct drm_plane_state *old_plane_state, *new_plane_state;
> + struct drm_plane_state *primary_state, *overlay_state = NULL;
> +
> + /* Check if primary plane is contained inside overlay */
> + for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
> + if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
> + if (drm_atomic_plane_disabling(plane->state, new_plane_state))
> + return 0;
> +
> + overlay_state = new_plane_state;
> + continue;
> + }
> + }
> +
> + /* check if we're making changes to the overlay plane */
> + if (!overlay_state)
> + return 0;
> +
> + /* check if overlay plane is enabled */
> + if (!overlay_state->crtc)
> + return 0;
> +
> + /* find the primary plane for the CRTC that the overlay is enabled on */
> + primary_state = drm_atomic_get_plane_state(state, overlay_state->crtc->primary);
> + if (IS_ERR(primary_state))
> + return PTR_ERR(primary_state);
> +
> + /* check if primary plane is enabled */
> + if (!primary_state->crtc)
> + return 0;
> +
> + /* Perform the bounds check to ensure the overlay plane covers the primary */
> + if (primary_state->crtc_x < overlay_state->crtc_x ||
> + primary_state->crtc_y < overlay_state->crtc_y ||
> + primary_state->crtc_x + primary_state->crtc_w > overlay_state->crtc_x + overlay_state->crtc_w ||
> + primary_state->crtc_y + primary_state->crtc_h > overlay_state->crtc_y + overlay_state->crtc_h) {
> + DRM_DEBUG_ATOMIC("Overlay plane is enabled with hardware cursor but does not fully cover primary plane\n");
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> /**
> * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
> * @dev: The DRM device
> @@ -10120,6 +10167,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
> goto fail;
> }
>
> + ret = validate_overlay(state);
> + if (ret)
> + goto fail;
> +
> /* Add new/modified planes */
> for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
> ret = dm_update_plane_state(dc, state, plane,
>
More information about the amd-gfx
mailing list