mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
drm/amd/display: Reject too small viewport size when validating plane
[why] Overlay won't move to a new positon if viewport size is smaller than what can be handled. It'd either disappear or stay at the old position. This condition is for example hit if overlay is moved too much outside of left or top edge of the screen, but it applies to any non-cursor plane type. [how] Reject this contidion at validation time. This gives the calling level a chance to handle this gracefully and avoid inconsistent behaivor. Signed-off-by: Nikola Cornij <nikola.cornij@amd.com> Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Acked-by: Anson Jacob <Anson.Jacob@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
e2dcd9b8b8
commit
40d916a260
3 changed files with 29 additions and 3 deletions
|
@ -6411,8 +6411,33 @@ static int dm_plane_helper_check_state(struct drm_plane_state *state,
|
|||
int min_scale = 0;
|
||||
int max_scale = INT_MAX;
|
||||
|
||||
/* Plane enabled? Get min/max allowed scaling factors from plane caps. */
|
||||
/* Plane enabled? Validate viewport and get scaling factors from plane caps. */
|
||||
if (fb && state->crtc) {
|
||||
/* Validate viewport to cover the case when only the position changes */
|
||||
if (state->plane->type != DRM_PLANE_TYPE_CURSOR) {
|
||||
int viewport_width = state->crtc_w;
|
||||
int viewport_height = state->crtc_h;
|
||||
|
||||
if (state->crtc_x < 0)
|
||||
viewport_width += state->crtc_x;
|
||||
else if (state->crtc_x + state->crtc_w > new_crtc_state->mode.crtc_hdisplay)
|
||||
viewport_width = new_crtc_state->mode.crtc_hdisplay - state->crtc_x;
|
||||
|
||||
if (state->crtc_y < 0)
|
||||
viewport_height += state->crtc_y;
|
||||
else if (state->crtc_y + state->crtc_h > new_crtc_state->mode.crtc_vdisplay)
|
||||
viewport_height = new_crtc_state->mode.crtc_vdisplay - state->crtc_y;
|
||||
|
||||
/* If completely outside of screen, viewport_width and/or viewport_height will be negative,
|
||||
* which is still OK to satisfy the condition below, thereby also covering these cases
|
||||
* (when plane is completely outside of screen).
|
||||
* x2 for width is because of pipe-split.
|
||||
*/
|
||||
if (viewport_width < MIN_VIEWPORT_SIZE*2 || viewport_height < MIN_VIEWPORT_SIZE)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get min/max allowed scaling factors from plane caps. */
|
||||
get_min_max_dc_plane_scaling(state->crtc->dev, fb,
|
||||
&min_downscale, &max_upscale);
|
||||
/*
|
||||
|
|
|
@ -1153,8 +1153,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
|||
|
||||
calculate_viewport(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->plane_res.scl_data.viewport.height < 12 ||
|
||||
pipe_ctx->plane_res.scl_data.viewport.width < 12) {
|
||||
if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE ||
|
||||
pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) {
|
||||
if (store_h_border_left) {
|
||||
restore_border_left_from_dst(pipe_ctx,
|
||||
store_h_border_left);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define MAX_PLANES 6
|
||||
#define MAX_STREAMS 6
|
||||
#define MAX_SINKS_PER_LINK 4
|
||||
#define MIN_VIEWPORT_SIZE 12
|
||||
|
||||
/*******************************************************************************
|
||||
* Display Core Interfaces
|
||||
|
|
Loading…
Reference in a new issue