Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 358a638e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: Fix source split validation"

parents 921b4d55 1ddddebe
Loading
Loading
Loading
Loading
+82 −44
Original line number Diff line number Diff line
@@ -2264,6 +2264,78 @@ static int __validate_multirect(struct msm_fb_data_type *mfd,
	return 0;
}

static int __check_source_split(struct mdp_input_layer *layer_list,
	struct mdss_mdp_pipe **pipe_list, u32 index,
	u32 left_lm_w, struct mdss_mdp_pipe **left_blend_pipe)
{
	int i = index - 1;
	struct mdp_input_layer *curr, *prev;
	struct mdp_rect *left, *right;
	bool match = false;
	struct mdss_mdp_pipe *left_pipe = NULL;

	/*
	 * check if current layer is at same z_order as any of the
	 * previous layers, and fail if any or both are async layers,
	 * as async layers should have unique z_order.
	 *
	 * If it has same z_order and qualifies as a right blend,
	 * pass a pointer to the pipe representing previous overlay or
	 * in other terms left blend layer.
	 *
	 * Following logic of selecting left_blend has an inherent
	 * assumption that layer list is sorted on dst_x within a
	 * same z_order. Otherwise it will fail based on z_order checks.
	 */
	curr = &layer_list[index];

	while (i >= 0) {
		if (layer_list[i].z_order == curr->z_order) {
			pr_debug("z=%d found match @ %d of %d\n",
				curr->z_order, i, index);
			match = true;
			break;
		}
		i--;
	}

	if (match) {
		left_pipe = pipe_list[i];
		prev = &layer_list[i];
		left = &prev->dst_rect;
		right = &curr->dst_rect;

		if ((curr->flags & MDP_LAYER_ASYNC)
			|| (prev->flags & MDP_LAYER_ASYNC)) {
			curr->error_code = -EINVAL;
			pr_err("async curr should have unique z_order\n");
			return curr->error_code;
		}

		/*
		 * check if curr is right blend by checking it's
		 * directly to the right.
		 */
		if (((left->x + left->w) == right->x) &&
		    (left->y == right->y) && (left->h == right->h)) {
			*left_blend_pipe = left_pipe;
			MDSS_XLOG(curr->z_order, i, index);
		}

		/*
		 * if the curr is right at the left lm boundary and
		 * src split is not required then right blend is not
		 * required as it will lie only on the left mixer
		 */
		if (!__layer_needs_src_split(prev) &&
		    ((left->x + left->w) == left_lm_w))
			*left_blend_pipe = NULL;
	}

	return 0;
}


/*
 * __validate_layers() - validate input layers
 * @mfd:	Framebuffer data structure for display
@@ -2294,13 +2366,14 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
	struct mdss_data_type *mdata = mfd_to_mdata(mfd);

	struct mdss_mdp_mixer *mixer = NULL;
	struct mdp_input_layer *layer, *prev_layer, *layer_list;
	struct mdp_input_layer *layer, *layer_list;
	struct mdss_mdp_validate_info_t *validate_info_list = NULL;
	bool is_single_layer = false, force_validate;
	enum layer_pipe_q pipe_q_type;
	enum layer_zorder_used zorder_used[MDSS_MDP_MAX_STAGE] = {0};
	enum mdss_mdp_pipe_rect rect_num;
	struct mdp_destination_scaler_data *ds_data;
	struct mdss_mdp_pipe *pipe_list[MAX_LAYER_COUNT] = {0};

	ret = mutex_lock_interruptible(&mdp5_data->ov_lock);
	if (ret)
@@ -2372,49 +2445,10 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
		dst_x = layer->dst_rect.x;
		left_blend_pipe = NULL;

		prev_layer = (i > 0) ? &layer_list[i - 1] : NULL;
		/*
		 * check if current layer is at same z_order as
		 * previous one, and fail if any or both are async layers,
		 * as async layers should have unique z_order.
		 *
		 * If it has same z_order and qualifies as a right blend,
		 * pass a pointer to the pipe representing previous overlay or
		 * in other terms left blend layer.
		 *
		 * Following logic of selecting left_blend has an inherent
		 * assumption that layer list is sorted on dst_x within a
		 * same z_order. Otherwise it will fail based on z_order checks.
		 */
		if (prev_layer && (prev_layer->z_order == layer->z_order)) {
			struct mdp_rect *left = &prev_layer->dst_rect;
			struct mdp_rect *right = &layer->dst_rect;

			if ((layer->flags & MDP_LAYER_ASYNC)
				|| (prev_layer->flags & MDP_LAYER_ASYNC)) {
				ret = -EINVAL;
				layer->error_code = ret;
				pr_err("async layer should have unique z_order\n");
		if ((i > 0) &&
		    __check_source_split(layer_list, pipe_list, i, left_lm_w,
		    &left_blend_pipe))
			goto validate_exit;
			}

			/*
			 * check if layer is right blend by checking it's
			 * directly to the right.
			 */
			if (((left->x + left->w) == right->x) &&
			    (left->y == right->y) && (left->h == right->h))
				left_blend_pipe = pipe;

			/*
			 * if the layer is right at the left lm boundary and
			 * src split is not required then right blend is not
			 * required as it will lie only on the left mixer
			 */
			if (!__layer_needs_src_split(prev_layer) &&
			    ((left->x + left->w) == left_lm_w))
				left_blend_pipe = NULL;
		}

		if (!is_split_lm(mfd) || __layer_needs_src_split(layer))
			z = LAYER_ZORDER_BOTH;
@@ -2459,6 +2493,8 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
			else
				left_plist[left_cnt++] = pipe;

			pipe_list[i] = pipe;

			if (layer->flags & MDP_LAYER_PP) {
				memcpy(&pipe->pp_cfg, layer->pp_info,
					sizeof(struct mdp_overlay_pp_params));
@@ -2551,6 +2587,8 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
		else
			left_plist[left_cnt++] = pipe;

		pipe_list[i] = pipe;

		pr_debug("id:0x%x flags:0x%x dst_x:%d\n",
			layer->pipe_ndx, layer->flags, layer->dst_rect.x);
		layer->z_order -= MDSS_MDP_STAGE_0;