osd: range of mouse is wrong under 4K mode [1/2]

PD#SWPL-2551

Problem:
range of mouse is wrong under 4K mode

Solution:
new cursor coordinate paras without using scale
add osd_cursor_hw_no_scale() to deal with it.

Verify:
verified on P212

Change-Id: I1748df569b96522eb58dc00af862983bca17815a
Signed-off-by: Jian Cao <jian.cao@amlogic.com>
This commit is contained in:
Jian Cao
2018-12-05 15:31:30 +08:00
committed by Dongjin Kim
parent b22a775925
commit f06b47ca96
3 changed files with 157 additions and 2 deletions

View File

@@ -1615,8 +1615,16 @@ static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var)
startx = fb_dev->osd_ctl.disp_start_x;
starty = fb_dev->osd_ctl.disp_start_y;
}
osd_cursor_hw(fbi->node, (s16)var->hot.x, (s16)var->hot.y, (s16)startx,
(s16)starty, fbi->var.xres, fbi->var.yres);
if (osd_hw.hwc_enable)
osd_cursor_hw_no_scale(fbi->node, (s16)var->hot.x,
(s16)var->hot.y, (s16)startx, (s16)starty,
fbi->var.xres, fbi->var.yres);
else
osd_cursor_hw(fbi->node, (s16)var->hot.x,
(s16)var->hot.y, (s16)startx, (s16)starty,
fbi->var.xres, fbi->var.yres);
return 0;
}

View File

@@ -8791,6 +8791,151 @@ void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w,
osd_hw.dispdata[OSD2].y_start, osd_hw.dispdata[OSD2].y_end);
}
void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart, s16 ystart,
u32 osd_w, u32 osd_h)
{
struct pandata_s disp_tmp;
struct vinfo_s *vinfo = NULL;
int w = 0, h = 0;
int w_diff = 0;
if (index != 1)
return;
osd_log_dbg2("cursor: x=%d, y=%d, x0=%d, y0=%d, w=%d, h=%d\n",
x, y, xstart, ystart, osd_w, osd_h);
if (osd_hw.free_scale_mode[OSD1]) {
if (osd_hw.free_scale_enable[OSD1])
memcpy(&disp_tmp, &osd_hw.cursor_dispdata[OSD1],
sizeof(struct pandata_s));
else
memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
sizeof(struct pandata_s));
} else
memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
sizeof(struct pandata_s));
if (osd_hw.field_out_en) {
disp_tmp.y_start *= 2;
disp_tmp.y_end *= 2;
}
if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
vinfo = get_current_vinfo();
if ((vinfo == NULL) || (vinfo->mode == VMODE_INIT_NULL))
return;
w = vinfo->width;
h = vinfo->height;
x = w - x;
y = h - y;
}
x += xstart;
y += ystart;
if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
if (osd_w >= osd_h)
w_diff = osd_w - osd_h;
else
w_diff = 0;
osd_hw.pandata[OSD2].x_start = w_diff;
osd_hw.pandata[OSD2].x_end = osd_w - 1;
osd_hw.pandata[OSD2].y_start = 0;
osd_hw.pandata[OSD2].y_end = osd_h - 1;
x -= osd_w;
y -= osd_h;
osd_log_dbg2("x=%d,y=%d\n", x, y);
}
/*
* Use pandata to show a partial cursor when it is at the edge because
* the registers can't have negative values and because we need to
* manually clip the cursor when it is past the edge. The edge is
* hardcoded to the OSD0 area.
*/
osd_hw.dispdata[OSD2].x_start = x;
osd_hw.dispdata[OSD2].y_start = y;
if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
if (x < disp_tmp.x_start) {
/* if negative position, set osd x pan. */
if ((disp_tmp.x_start - x) < osd_w) {
osd_hw.pandata[OSD2].x_start =
w_diff;
osd_hw.pandata[OSD2].x_end =
osd_w - 1 - (disp_tmp.x_start - x);
}
/* set osd x to disp_tmp.x_start */
osd_hw.dispdata[OSD2].x_start = disp_tmp.x_start;
}
if (y < disp_tmp.y_start) {
/* if negative position, set osd y pan. */
if ((disp_tmp.y_start - y) < osd_h) {
osd_hw.pandata[OSD2].y_start = 0;
osd_hw.pandata[OSD2].y_end =
osd_h - 1 - (disp_tmp.y_start - y);
}
/* set osd y to disp_tmp.y_start */
osd_hw.dispdata[OSD2].y_start = disp_tmp.y_start;
}
} else {
if (x < disp_tmp.x_start) {
/* if negative position, set osd to 0,y and pan. */
if ((disp_tmp.x_start - x) < osd_w) {
osd_hw.pandata[OSD2].x_start =
disp_tmp.x_start - x;
osd_hw.pandata[OSD2].x_end = osd_w - 1;
}
osd_hw.dispdata[OSD2].x_start = 0;
} else {
osd_hw.pandata[OSD2].x_start = 0;
if (x + osd_w > disp_tmp.x_end) {
/*
* if past positive edge,
* set osd to inside of the edge and pan.
*/
if (x < disp_tmp.x_end)
osd_hw.pandata[OSD2].x_end =
disp_tmp.x_end - x;
} else
osd_hw.pandata[OSD2].x_end = osd_w - 1;
}
if (y < disp_tmp.y_start) {
if ((disp_tmp.y_start - y) < osd_h) {
osd_hw.pandata[OSD2].y_start =
disp_tmp.y_start - y;
osd_hw.pandata[OSD2].y_end = osd_h - 1;
}
osd_hw.dispdata[OSD2].y_start = 0;
} else {
osd_hw.pandata[OSD2].y_start = 0;
if (y + osd_h > disp_tmp.y_end) {
if (y < disp_tmp.y_end)
osd_hw.pandata[OSD2].y_end =
disp_tmp.y_end - y;
} else
osd_hw.pandata[OSD2].y_end = osd_h - 1;
}
}
if (osd_hw.field_out_en)
osd_hw.dispdata[OSD2].y_start /= 2;
osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start +
osd_hw.pandata[OSD2].x_end - osd_hw.pandata[OSD2].x_start;
osd_hw.dispdata[OSD2].y_end = osd_hw.dispdata[OSD2].y_start +
osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start;
add_to_update_list(OSD2, OSD_COLOR_MODE);
add_to_update_list(OSD2, DISP_GEOMETRY);
osd_log_dbg2("dispdata: %d,%d,%d,%d\n",
osd_hw.dispdata[OSD2].x_start, osd_hw.dispdata[OSD2].x_end,
osd_hw.dispdata[OSD2].y_start, osd_hw.dispdata[OSD2].y_end);
}
void osd_suspend_hw(void)
{
if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {

View File

@@ -128,6 +128,8 @@ extern int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd);
extern s64 osd_wait_vsync_event(void);
extern void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart,
u32 osd_w, u32 osd_h);
extern void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart,
s16 ystart, u32 osd_w, u32 osd_h);
extern void osd_init_scan_mode(void);
extern void osd_suspend_hw(void);
extern void osd_resume_hw(void);