mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-19 17:53:26 -04:00
drm/amd/display: Reverse the visual confirm recouts
[WHY] When checking if a pipe can disable cursor to prevent duplicate cursors, having visual confirm on will prevent disabling cursors on planes which cover the bottom of the screen. [HOW] When checking if a plane can disable visual confirm, the pipe first reverses these calculations before doing the checks. Reviewed-by: Alvin Lee <alvin.lee2@amd.com> Signed-off-by: Peterson Guo <peterson.guo@amd.com> Signed-off-by: Wayne Lin <wayne.lin@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
b9e124a565
commit
3c50bf2196
@@ -941,6 +941,17 @@ static void calculate_adjust_recout_for_visual_confirm(struct pipe_ctx *pipe_ctx
|
||||
*base_offset = VISUAL_CONFIRM_BASE_DEFAULT;
|
||||
}
|
||||
|
||||
static void reverse_adjust_recout_for_visual_confirm(struct rect *recout,
|
||||
struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
int dpp_offset, base_offset;
|
||||
|
||||
calculate_adjust_recout_for_visual_confirm(pipe_ctx, &base_offset,
|
||||
&dpp_offset);
|
||||
recout->height += base_offset;
|
||||
recout->height += dpp_offset;
|
||||
}
|
||||
|
||||
static void adjust_recout_for_visual_confirm(struct rect *recout,
|
||||
struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
@@ -1641,6 +1652,62 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
return res;
|
||||
}
|
||||
|
||||
bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct pipe_ctx *test_pipe, *split_pipe;
|
||||
struct rect r1 = pipe_ctx->plane_res.scl_data.recout;
|
||||
int r1_right, r1_bottom;
|
||||
int cur_layer = pipe_ctx->plane_state->layer_index;
|
||||
|
||||
reverse_adjust_recout_for_visual_confirm(&r1, pipe_ctx);
|
||||
r1_right = r1.x + r1.width;
|
||||
r1_bottom = r1.y + r1.height;
|
||||
|
||||
/**
|
||||
* Disable the cursor if there's another pipe above this with a
|
||||
* plane that contains this pipe's viewport to prevent double cursor
|
||||
* and incorrect scaling artifacts.
|
||||
*/
|
||||
for (test_pipe = pipe_ctx->top_pipe; test_pipe;
|
||||
test_pipe = test_pipe->top_pipe) {
|
||||
struct rect r2;
|
||||
int r2_right, r2_bottom;
|
||||
// Skip invisible layer and pipe-split plane on same layer
|
||||
if (!test_pipe->plane_state ||
|
||||
!test_pipe->plane_state->visible ||
|
||||
test_pipe->plane_state->layer_index == cur_layer)
|
||||
continue;
|
||||
|
||||
r2 = test_pipe->plane_res.scl_data.recout;
|
||||
reverse_adjust_recout_for_visual_confirm(&r2, test_pipe);
|
||||
r2_right = r2.x + r2.width;
|
||||
r2_bottom = r2.y + r2.height;
|
||||
|
||||
/**
|
||||
* There is another half plane on same layer because of
|
||||
* pipe-split, merge together per same height.
|
||||
*/
|
||||
for (split_pipe = pipe_ctx->top_pipe; split_pipe;
|
||||
split_pipe = split_pipe->top_pipe)
|
||||
if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
|
||||
struct rect r2_half;
|
||||
|
||||
r2_half = split_pipe->plane_res.scl_data.recout;
|
||||
reverse_adjust_recout_for_visual_confirm(&r2_half, split_pipe);
|
||||
r2.x = min(r2_half.x, r2.x);
|
||||
r2.width = r2.width + r2_half.width;
|
||||
r2_right = r2.x + r2.width;
|
||||
r2_bottom = min(r2_bottom, r2_half.y + r2_half.height);
|
||||
break;
|
||||
}
|
||||
|
||||
if (r1.x >= r2.x && r1.y >= r2.y && r1_right <= r2_right && r1_bottom <= r2_bottom)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
enum dc_status resource_build_scaling_params_for_context(
|
||||
const struct dc *dc,
|
||||
|
||||
@@ -991,57 +991,11 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv)
|
||||
DC_LOG_DEBUG(" is_cw6_en : %d", diag_data.is_cw6_enabled);
|
||||
}
|
||||
|
||||
static bool dc_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct pipe_ctx *test_pipe, *split_pipe;
|
||||
const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
|
||||
struct rect r1 = scl_data->recout, r2, r2_half;
|
||||
int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
|
||||
int cur_layer = pipe_ctx->plane_state->layer_index;
|
||||
|
||||
/**
|
||||
* Disable the cursor if there's another pipe above this with a
|
||||
* plane that contains this pipe's viewport to prevent double cursor
|
||||
* and incorrect scaling artifacts.
|
||||
*/
|
||||
for (test_pipe = pipe_ctx->top_pipe; test_pipe;
|
||||
test_pipe = test_pipe->top_pipe) {
|
||||
// Skip invisible layer and pipe-split plane on same layer
|
||||
if (!test_pipe->plane_state->visible || test_pipe->plane_state->layer_index == cur_layer)
|
||||
continue;
|
||||
|
||||
r2 = test_pipe->plane_res.scl_data.recout;
|
||||
r2_r = r2.x + r2.width;
|
||||
r2_b = r2.y + r2.height;
|
||||
|
||||
/**
|
||||
* There is another half plane on same layer because of
|
||||
* pipe-split, merge together per same height.
|
||||
*/
|
||||
for (split_pipe = pipe_ctx->top_pipe; split_pipe;
|
||||
split_pipe = split_pipe->top_pipe)
|
||||
if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
|
||||
r2_half = split_pipe->plane_res.scl_data.recout;
|
||||
r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
|
||||
r2.width = r2.width + r2_half.width;
|
||||
r2_r = r2.x + r2.width;
|
||||
break;
|
||||
}
|
||||
|
||||
if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool dc_dmub_should_update_cursor_data(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
if (pipe_ctx->plane_state != NULL) {
|
||||
if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
|
||||
return false;
|
||||
|
||||
if (dc_can_pipe_disable_cursor(pipe_ctx))
|
||||
if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ||
|
||||
resource_can_pipe_disable_cursor(pipe_ctx))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3432,52 +3432,6 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
|
||||
hubbub->funcs->update_dchub(hubbub, dh_data);
|
||||
}
|
||||
|
||||
static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct pipe_ctx *test_pipe, *split_pipe;
|
||||
const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
|
||||
struct rect r1 = scl_data->recout, r2, r2_half;
|
||||
int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
|
||||
int cur_layer = pipe_ctx->plane_state->layer_index;
|
||||
|
||||
/**
|
||||
* Disable the cursor if there's another pipe above this with a
|
||||
* plane that contains this pipe's viewport to prevent double cursor
|
||||
* and incorrect scaling artifacts.
|
||||
*/
|
||||
for (test_pipe = pipe_ctx->top_pipe; test_pipe;
|
||||
test_pipe = test_pipe->top_pipe) {
|
||||
// Skip invisible layer and pipe-split plane on same layer
|
||||
if (!test_pipe->plane_state ||
|
||||
!test_pipe->plane_state->visible ||
|
||||
test_pipe->plane_state->layer_index == cur_layer)
|
||||
continue;
|
||||
|
||||
r2 = test_pipe->plane_res.scl_data.recout;
|
||||
r2_r = r2.x + r2.width;
|
||||
r2_b = r2.y + r2.height;
|
||||
|
||||
/**
|
||||
* There is another half plane on same layer because of
|
||||
* pipe-split, merge together per same height.
|
||||
*/
|
||||
for (split_pipe = pipe_ctx->top_pipe; split_pipe;
|
||||
split_pipe = split_pipe->top_pipe)
|
||||
if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
|
||||
r2_half = split_pipe->plane_res.scl_data.recout;
|
||||
r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
|
||||
r2.width = r2.width + r2_half.width;
|
||||
r2_r = r2.x + r2.width;
|
||||
break;
|
||||
}
|
||||
|
||||
if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
|
||||
@@ -3577,7 +3531,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
||||
== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
|
||||
pos_cpy.enable = false;
|
||||
|
||||
if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx))
|
||||
if (pos_cpy.enable && resource_can_pipe_disable_cursor(pipe_ctx))
|
||||
pos_cpy.enable = false;
|
||||
|
||||
|
||||
|
||||
@@ -972,52 +972,6 @@ void dcn401_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
|
||||
REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, enable);
|
||||
}
|
||||
|
||||
static bool dcn401_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct pipe_ctx *test_pipe, *split_pipe;
|
||||
const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
|
||||
struct rect r1 = scl_data->recout, r2, r2_half;
|
||||
int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
|
||||
int cur_layer = pipe_ctx->plane_state->layer_index;
|
||||
|
||||
/**
|
||||
* Disable the cursor if there's another pipe above this with a
|
||||
* plane that contains this pipe's viewport to prevent double cursor
|
||||
* and incorrect scaling artifacts.
|
||||
*/
|
||||
for (test_pipe = pipe_ctx->top_pipe; test_pipe;
|
||||
test_pipe = test_pipe->top_pipe) {
|
||||
// Skip invisible layer and pipe-split plane on same layer
|
||||
if (!test_pipe->plane_state ||
|
||||
!test_pipe->plane_state->visible ||
|
||||
test_pipe->plane_state->layer_index == cur_layer)
|
||||
continue;
|
||||
|
||||
r2 = test_pipe->plane_res.scl_data.recout;
|
||||
r2_r = r2.x + r2.width;
|
||||
r2_b = r2.y + r2.height;
|
||||
|
||||
/**
|
||||
* There is another half plane on same layer because of
|
||||
* pipe-split, merge together per same height.
|
||||
*/
|
||||
for (split_pipe = pipe_ctx->top_pipe; split_pipe;
|
||||
split_pipe = split_pipe->top_pipe)
|
||||
if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
|
||||
r2_half = split_pipe->plane_res.scl_data.recout;
|
||||
r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
|
||||
r2.width = r2.width + r2_half.width;
|
||||
r2_r = r2.x + r2.width;
|
||||
break;
|
||||
}
|
||||
|
||||
if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void adjust_hotspot_between_slices_for_2x_magnify(uint32_t cursor_width, struct dc_cursor_position *pos_cpy)
|
||||
{
|
||||
if (cursor_width <= 128) {
|
||||
@@ -1208,7 +1162,7 @@ void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
||||
pos_cpy.x = (uint32_t)x_pos;
|
||||
pos_cpy.y = (uint32_t)y_pos;
|
||||
|
||||
if (pos_cpy.enable && dcn401_can_pipe_disable_cursor(pipe_ctx))
|
||||
if (pos_cpy.enable && resource_can_pipe_disable_cursor(pipe_ctx))
|
||||
pos_cpy.enable = false;
|
||||
|
||||
x_pos = pos_cpy.x - param.recout.x;
|
||||
|
||||
@@ -152,6 +152,8 @@ bool resource_attach_surfaces_to_context(
|
||||
struct dc_state *context,
|
||||
const struct resource_pool *pool);
|
||||
|
||||
bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx);
|
||||
|
||||
#define FREE_PIPE_INDEX_NOT_FOUND -1
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user