Commit 4ba6b7a6 authored by Jessica Zhang's avatar Jessica Zhang Committed by Dmitry Baryshkov
Browse files

drm/atomic: Move framebuffer checks to helper



Currently framebuffer checks happen directly in
drm_atomic_plane_check(). Move these checks into their own helper
method.

Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Acked-by: default avatarSebastian Wick <sebastian@sebastianwick.net>
Signed-off-by: default avatarJessica Zhang <quic_jesszhan@quicinc.com>
Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20231027-solid-fill-v7-6-780188bfa7b2@quicinc.com
parent e86413f5
Loading
Loading
Loading
Loading
+73 −57
Original line number Diff line number Diff line
@@ -589,6 +589,76 @@ plane_switching_crtc(const struct drm_plane_state *old_plane_state,
	return true;
}

static int drm_atomic_plane_check_fb(const struct drm_plane_state *state)
{
	struct drm_plane *plane = state->plane;
	const struct drm_framebuffer *fb = state->fb;
	struct drm_mode_rect *clips;

	uint32_t num_clips;
	unsigned int fb_width, fb_height;
	int ret;

	/* Check whether this plane supports the fb pixel format. */
	ret = drm_plane_check_pixel_format(plane, fb->format->format,
					   fb->modifier);

	if (ret) {
		drm_dbg_atomic(plane->dev,
			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
			       plane->base.id, plane->name,
			       &fb->format->format, fb->modifier);
		return ret;
	}

	fb_width = fb->width << 16;
	fb_height = fb->height << 16;

	/* Make sure source coordinates are inside the fb. */
	if (state->src_w > fb_width ||
	    state->src_x > fb_width - state->src_w ||
	    state->src_h > fb_height ||
	    state->src_y > fb_height - state->src_h) {
		drm_dbg_atomic(plane->dev,
			       "[PLANE:%d:%s] invalid source coordinates "
			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
			       plane->base.id, plane->name,
			       state->src_w >> 16,
			       ((state->src_w & 0xffff) * 15625) >> 10,
			       state->src_h >> 16,
			       ((state->src_h & 0xffff) * 15625) >> 10,
			       state->src_x >> 16,
			       ((state->src_x & 0xffff) * 15625) >> 10,
			       state->src_y >> 16,
			       ((state->src_y & 0xffff) * 15625) >> 10,
			       fb->width, fb->height);
		return -ENOSPC;
	}

	clips = __drm_plane_get_damage_clips(state);
	num_clips = drm_plane_get_damage_clips_count(state);

	/* Make sure damage clips are valid and inside the fb. */
	while (num_clips > 0) {
		if (clips->x1 >= clips->x2 ||
		    clips->y1 >= clips->y2 ||
		    clips->x1 < 0 ||
		    clips->y1 < 0 ||
		    clips->x2 > fb_width ||
		    clips->y2 > fb_height) {
			drm_dbg_atomic(plane->dev,
				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
				       plane->base.id, plane->name, clips->x1,
				       clips->y1, clips->x2, clips->y2);
			return -EINVAL;
		}
		clips++;
		num_clips--;
	}

	return 0;
}

/**
 * drm_atomic_plane_check - check plane state
 * @old_plane_state: old plane state to check
@@ -605,9 +675,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
	struct drm_plane *plane = new_plane_state->plane;
	struct drm_crtc *crtc = new_plane_state->crtc;
	const struct drm_framebuffer *fb = new_plane_state->fb;
	unsigned int fb_width, fb_height;
	struct drm_mode_rect *clips;
	uint32_t num_clips;
	int ret;

	/* either *both* CRTC and FB must be set, or neither */
@@ -634,17 +701,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
		return -EINVAL;
	}

	/* Check whether this plane supports the fb pixel format. */
	ret = drm_plane_check_pixel_format(plane, fb->format->format,
					   fb->modifier);
	if (ret) {
		drm_dbg_atomic(plane->dev,
			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
			       plane->base.id, plane->name,
			       &fb->format->format, fb->modifier);
		return ret;
	}

	/* Give drivers some help against integer overflows */
	if (new_plane_state->crtc_w > INT_MAX ||
	    new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
@@ -658,50 +714,10 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
		return -ERANGE;
	}

	fb_width = fb->width << 16;
	fb_height = fb->height << 16;

	/* Make sure source coordinates are inside the fb. */
	if (new_plane_state->src_w > fb_width ||
	    new_plane_state->src_x > fb_width - new_plane_state->src_w ||
	    new_plane_state->src_h > fb_height ||
	    new_plane_state->src_y > fb_height - new_plane_state->src_h) {
		drm_dbg_atomic(plane->dev,
			       "[PLANE:%d:%s] invalid source coordinates "
			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
			       plane->base.id, plane->name,
			       new_plane_state->src_w >> 16,
			       ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
			       new_plane_state->src_h >> 16,
			       ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
			       new_plane_state->src_x >> 16,
			       ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
			       new_plane_state->src_y >> 16,
			       ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
			       fb->width, fb->height);
		return -ENOSPC;
	}

	clips = __drm_plane_get_damage_clips(new_plane_state);
	num_clips = drm_plane_get_damage_clips_count(new_plane_state);

	/* Make sure damage clips are valid and inside the fb. */
	while (num_clips > 0) {
		if (clips->x1 >= clips->x2 ||
		    clips->y1 >= clips->y2 ||
		    clips->x1 < 0 ||
		    clips->y1 < 0 ||
		    clips->x2 > fb_width ||
		    clips->y2 > fb_height) {
			drm_dbg_atomic(plane->dev,
				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
				       plane->base.id, plane->name, clips->x1,
				       clips->y1, clips->x2, clips->y2);
			return -EINVAL;
		}
		clips++;
		num_clips--;
	}
	ret = drm_atomic_plane_check_fb(new_plane_state);
	if (ret)
		return ret;

	if (plane_switching_crtc(old_plane_state, new_plane_state)) {
		drm_dbg_atomic(plane->dev,