Merge "msm: mdss: Fix source split validation"
This commit is contained in:
commit
358a638e69
1 changed files with 82 additions and 44 deletions
|
@ -2264,6 +2264,78 @@ static int __validate_multirect(struct msm_fb_data_type *mfd,
|
||||||
return 0;
|
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
|
* __validate_layers() - validate input layers
|
||||||
* @mfd: Framebuffer data structure for display
|
* @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_data_type *mdata = mfd_to_mdata(mfd);
|
||||||
|
|
||||||
struct mdss_mdp_mixer *mixer = NULL;
|
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;
|
struct mdss_mdp_validate_info_t *validate_info_list = NULL;
|
||||||
bool is_single_layer = false, force_validate;
|
bool is_single_layer = false, force_validate;
|
||||||
enum layer_pipe_q pipe_q_type;
|
enum layer_pipe_q pipe_q_type;
|
||||||
enum layer_zorder_used zorder_used[MDSS_MDP_MAX_STAGE] = {0};
|
enum layer_zorder_used zorder_used[MDSS_MDP_MAX_STAGE] = {0};
|
||||||
enum mdss_mdp_pipe_rect rect_num;
|
enum mdss_mdp_pipe_rect rect_num;
|
||||||
struct mdp_destination_scaler_data *ds_data;
|
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);
|
ret = mutex_lock_interruptible(&mdp5_data->ov_lock);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -2372,49 +2445,10 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
|
||||||
dst_x = layer->dst_rect.x;
|
dst_x = layer->dst_rect.x;
|
||||||
left_blend_pipe = NULL;
|
left_blend_pipe = NULL;
|
||||||
|
|
||||||
prev_layer = (i > 0) ? &layer_list[i - 1] : NULL;
|
if ((i > 0) &&
|
||||||
/*
|
__check_source_split(layer_list, pipe_list, i, left_lm_w,
|
||||||
* check if current layer is at same z_order as
|
&left_blend_pipe))
|
||||||
* 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");
|
|
||||||
goto validate_exit;
|
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))
|
if (!is_split_lm(mfd) || __layer_needs_src_split(layer))
|
||||||
z = LAYER_ZORDER_BOTH;
|
z = LAYER_ZORDER_BOTH;
|
||||||
|
@ -2459,6 +2493,8 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
|
||||||
else
|
else
|
||||||
left_plist[left_cnt++] = pipe;
|
left_plist[left_cnt++] = pipe;
|
||||||
|
|
||||||
|
pipe_list[i] = pipe;
|
||||||
|
|
||||||
if (layer->flags & MDP_LAYER_PP) {
|
if (layer->flags & MDP_LAYER_PP) {
|
||||||
memcpy(&pipe->pp_cfg, layer->pp_info,
|
memcpy(&pipe->pp_cfg, layer->pp_info,
|
||||||
sizeof(struct mdp_overlay_pp_params));
|
sizeof(struct mdp_overlay_pp_params));
|
||||||
|
@ -2551,6 +2587,8 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
|
||||||
else
|
else
|
||||||
left_plist[left_cnt++] = pipe;
|
left_plist[left_cnt++] = pipe;
|
||||||
|
|
||||||
|
pipe_list[i] = pipe;
|
||||||
|
|
||||||
pr_debug("id:0x%x flags:0x%x dst_x:%d\n",
|
pr_debug("id:0x%x flags:0x%x dst_x:%d\n",
|
||||||
layer->pipe_ndx, layer->flags, layer->dst_rect.x);
|
layer->pipe_ndx, layer->flags, layer->dst_rect.x);
|
||||||
layer->z_order -= MDSS_MDP_STAGE_0;
|
layer->z_order -= MDSS_MDP_STAGE_0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue