All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/amd/display: Fix two cursor duplication when using overlay
@ 2021-04-07 21:49 Rodrigo Siqueira
  2021-04-08 18:37 ` Harry Wentland
  0 siblings, 1 reply; 2+ messages in thread
From: Rodrigo Siqueira @ 2021-04-07 21:49 UTC (permalink / raw)
  To: amd-gfx; +Cc: Hersen Wu, Harry Wentland, Nicholas Kazlauskas, Louis Li

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.

Cc: Louis Li <Ching-shih.Li@amd.com>
Cc: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Cc: Harry Wentland <Harry.Wentland@amd.com>
Cc: Hersen Wu <hersenxs.wu@amd.com>
Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 59 +++++++++++++++++++
 1 file changed, 59 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 ac6ab35f89b2..5ae6d61e83f1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9939,6 +9939,61 @@ 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, *cursor_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;
+
+	/* check if cursor plane is enabled */
+	cursor_state = drm_atomic_get_plane_state(state, overlay_state->crtc->cursor);
+	if (IS_ERR(cursor_state))
+		return PTR_ERR(cursor_state);
+
+	if (drm_atomic_plane_disabling(plane->state, cursor_state))
+		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
@@ -10113,6 +10168,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,
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] drm/amd/display: Fix two cursor duplication when using overlay
  2021-04-07 21:49 [PATCH] drm/amd/display: Fix two cursor duplication when using overlay Rodrigo Siqueira
@ 2021-04-08 18:37 ` Harry Wentland
  0 siblings, 0 replies; 2+ messages in thread
From: Harry Wentland @ 2021-04-08 18:37 UTC (permalink / raw)
  To: Rodrigo Siqueira, amd-gfx; +Cc: Hersen Wu, Nicholas Kazlauskas, Louis Li



On 2021-04-07 5:49 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.
> 
> Cc: Louis Li <Ching-shih.Li@amd.com>
> Cc: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
> Cc: Harry Wentland <Harry.Wentland@amd.com>
> Cc: Hersen Wu <hersenxs.wu@amd.com>
> Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>

Reviewed-by: Harry Wentland <harry.wentland@amd.com>

Harry

> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 59 +++++++++++++++++++
>   1 file changed, 59 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 ac6ab35f89b2..5ae6d61e83f1 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -9939,6 +9939,61 @@ 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, *cursor_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;
> +
> +	/* check if cursor plane is enabled */
> +	cursor_state = drm_atomic_get_plane_state(state, overlay_state->crtc->cursor);
> +	if (IS_ERR(cursor_state))
> +		return PTR_ERR(cursor_state);
> +
> +	if (drm_atomic_plane_disabling(plane->state, cursor_state))
> +		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
> @@ -10113,6 +10168,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,
> 

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-04-08 18:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-07 21:49 [PATCH] drm/amd/display: Fix two cursor duplication when using overlay Rodrigo Siqueira
2021-04-08 18:37 ` Harry Wentland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.