From a9cc890ffea21fa492678b1755a263120cbddf0e Mon Sep 17 00:00:00 2001 From: Tim Yamin Date: Mon, 20 Apr 2009 20:29:11 -0700 Subject: [PATCH] DSS2: OMAPFB: Translate X/Y coordinates for the video planes when rotating. When rotating the video planes, translate the X/Y coordinates such that a [0,0] from userspace always maps to the correct upper left corner of the display. This patch assumes that you rotate plane 0 before rotating plane 1. Patch also corrects the scaling parameters so that the video is displayed in the correct orientation (vertically, instead of horizontally) when rotating by 90 / 270 degrees. Signed-off-by: Tim Yamin --- drivers/video/omap2/dss/dispc.c | 16 ++++++++++++---- drivers/video/omap2/dss/overlay.c | 6 ++++++ drivers/video/omap2/omapfb/omapfb-ioctl.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 7e551c2..bece91d 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1580,10 +1580,18 @@ static int _dispc_setup_plane(enum omap_plane plane, _dispc_set_pic_size(plane, width, height); if (plane != OMAP_DSS_GFX) { - _dispc_set_scaling(plane, width, height, - out_width, out_height, - ilace, five_taps, fieldmode); - _dispc_set_vid_size(plane, out_width, out_height); + if (rotation == 1 || rotation == 3) { + _dispc_set_scaling(plane, width, height, + out_height, out_width, + ilace, five_taps, fieldmode); + _dispc_set_vid_size(plane, out_height, out_width); + } else { + _dispc_set_scaling(plane, width, height, + out_width, out_height, + ilace, five_taps, fieldmode); + _dispc_set_vid_size(plane, out_width, out_height); + } + _dispc_set_vid_color_conv(plane, cconv); } diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index c047206..a1a02b5 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -344,6 +344,20 @@ outh = info->out_height; } + if ((ovl->supported_modes & info->color_mode) == 0) { + DSSERR("overlay doesn't support mode %d\n", info->color_mode); + return -EINVAL; + } + + if (ovl->id != OMAP_DSS_GFX && (info->rotation == 1 || + info->rotation == 3)) { + if(outw > dh || outh > dw) + return -EINVAL; + + /* If coordinates are invalid, they will be clipped later... */ + return 0; + } + if (dw < info->pos_x + outw) { DSSDBG("check_overlay failed 1: %d < %d + %d\n", dw, info->pos_x, outw); @@ -356,11 +370,6 @@ return -EINVAL; } - if ((ovl->supported_modes & info->color_mode) == 0) { - DSSERR("overlay doesn't support mode %d\n", info->color_mode); - return -EINVAL; - } - return 0; } diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 79d8916..b548f62 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -400,7 +400,7 @@ struct omap_overlay *ovl; bool ilace = 0; int outw, outh; - int r; + int r, pos_x = 0, pos_y = 0; int num_planes_enabled = 0; DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); @@ -451,11 +451,51 @@ else outh = ovl->info.out_height; + if (ovl->id != OMAP_DSS_GFX && ovl->info.rotation != 0) { + /* We need to rotate pos_x and pos_y with respect + to OMAP_DSS_GFX */ + + u16 dw, dh; + display->get_resolution(display, &dw, &dh); + + DSSDBG("plane pos was: (%d, %d), %dx%d, scr: %dx%d \n", ovl->info.pos_x, + ovl->info.pos_y, outw, outh, dw, dh); + + switch (ovl->info.rotation) { + case 1: + pos_y = ovl->info.pos_x; + pos_x = dw - ovl->info.pos_y - outh; + break; + case 2: + pos_x = dw - ovl->info.pos_x - outw; + pos_y = dh - ovl->info.pos_y - outh; + break; + case 3: + pos_x = ovl->info.pos_y; + pos_y = dh - ovl->info.pos_x - outw; + break; + } + + /* Check sanity */ + if (ovl->info.rotation != 2) { + if (dw < pos_x + outh) + pos_x = pos_y = 0; + else if (dh < pos_y + outw) + pos_x = pos_y = 0; + } else if ( (dw < ovl->info.pos_x + outw) || (dh < ovl->info.pos_y + outh) ) + pos_x = pos_y = 0; + + DSSDBG("pos_x is %d, pos_y is %d\n", pos_x, pos_y); + } else { + pos_x = ovl->info.pos_x; + pos_y = ovl->info.pos_y; + } + r = dispc_setup_plane(ovl->id, ovl->manager->id, ovl->info.paddr, ovl->info.screen_width, - ovl->info.pos_x, - ovl->info.pos_y, + pos_x, + pos_y, ovl->info.width, ovl->info.height, outw, diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 79d8916..b548f62 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -484,22 +484,7 @@ if (var->rotate != fbi->var.rotate) { DBG("rotation changing\n"); - ofbi->rotation = var->rotate; - - if (abs(var->rotate - fbi->var.rotate) != 2) { - int tmp; - DBG("rotate changing 90/270 degrees. " - "swapping x/y res\n"); - - tmp = var->yres; - var->yres = var->xres; - var->xres = tmp; - - tmp = var->yres_virtual; - var->yres_virtual = var->xres_virtual; - var->xres_virtual = tmp; - } } xres_min = OMAPFB_PLANE_XRES_MIN;