ARM: tegra: dc: clip invalid windows to screen res
Jon Mayo [Fri, 29 Apr 2011 03:25:13 +0000 (20:25 -0700)]
clip invalid windows to fix screen size, failure to do so causes display
errors that result in corrupted display and invalid video modes.
prints a warning only once, if this warning is present in the logs then
there is a misbehaving application.

Bug 821094

Original-Change-Id: Ief7b6379026e6abeb31a28aabf920618edd7ab44
Reviewed-on: http://git-master/r/29759
Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>
Tested-by: Jonathan Mayo <jmayo@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>

Rebase-Id: Rbbd1c33e5d4b58b5ddc8a4910b6851dc9bb73d63

drivers/video/tegra/dc/overlay.c
drivers/video/tegra/fb.c

index 47a6f49..1e16b72 100644 (file)
@@ -159,15 +159,28 @@ static int tegra_overlay_set_windowattr(struct tegra_overlay_info *overlay,
        win->out_w = flip_win->attr.out_w;
        win->out_h = flip_win->attr.out_h;
 
-       if ((((win->out_x + win->out_w) > xres) && (win->out_x < xres)) ||
-               (((win->out_y + win->out_h) > yres) && (win->out_y < yres))) {
-               pr_warning("outside of FB: "
-                               "FB=(%d,%d,%d,%d) "
-                               "src=(%d,%d,%d,%d) ",
-                               "dst=(%d,%d,%d,%d)",
-                               0, 0, xres, yres,
-                               win->x, win->y, win->w, win->h,
-                               win->out_x, win->out_y, win->out_w, win->out_h);
+       WARN_ONCE(win->out_x >= xres,
+               "%s:application window x offset exceeds display width(%d)\n",
+               dev_name(&win->dc->ndev->dev), win->out_x, xres);
+       WARN_ONCE(win->out_y >= yres,
+               "%s:application window y offset exceeds display height(%d)\n",
+               dev_name(&win->dc->ndev->dev), win->out_y, yres);
+       WARN_ONCE(win->out_x + win->out_w > xres && win->out_x < xres,
+               "%s:application window width(%d) exceeds display width(%d)\n",
+               dev_name(&win->dc->ndev->dev), win->out_x + win->out_w, xres);
+       WARN_ONCE(win->out_y + win->out_h > yres && win->out_y < yres,
+               "%s:application window height(%d) exceeds display height(%d)\n",
+               dev_name(&win->dc->ndev->dev), win->out_y + win->out_h, yres);
+
+       if (((win->out_x + win->out_w) > xres) && (win->out_x < xres)) {
+               long new_w = xres - win->out_x;
+               win->w = win->w * new_w / win->out_w;
+               win->out_w = new_w;
+       }
+       if (((win->out_y + win->out_h) > yres) && (win->out_y < yres)) {
+               long new_h = yres - win->out_y;
+               win->h = win->h * new_h / win->out_h;
+               win->out_h = new_h;
        }
 
        win->z = flip_win->attr.z;
index 2872757..4f61817 100644 (file)
@@ -401,15 +401,28 @@ static int tegra_fb_set_windowattr(struct tegra_fb_info *tegra_fb,
        win->out_w = flip_win->attr.out_w;
        win->out_h = flip_win->attr.out_h;
 
-       if ((((win->out_x + win->out_w) > xres) && (win->out_x < xres)) ||
-               (((win->out_y + win->out_h) > yres) && (win->out_y < yres))) {
-               pr_warning("outside of FB: "
-                               "FB=(%d,%d,%d,%d) "
-                               "src=(%d,%d,%d,%d) ",
-                               "dst=(%d,%d,%d,%d)",
-                               0, 0, xres, yres,
-                               win->x, win->y, win->w, win->h,
-                               win->out_x, win->out_y, win->out_w, win->out_h);
+       WARN_ONCE(win->out_x >= xres,
+               "%s:application window x offset exceeds display width(%d)\n",
+               dev_name(&win->dc->ndev->dev), win->out_x, xres);
+       WARN_ONCE(win->out_y >= yres,
+               "%s:application window y offset exceeds display height(%d)\n",
+               dev_name(&win->dc->ndev->dev), win->out_y, yres);
+       WARN_ONCE(win->out_x + win->out_w > xres && win->out_x < xres,
+               "%s:application window width(%d) exceeds display width(%d)\n",
+               dev_name(&win->dc->ndev->dev), win->out_x + win->out_w, xres);
+       WARN_ONCE(win->out_y + win->out_h > yres && win->out_y < yres,
+               "%s:application window height(%d) exceeds display height(%d)\n",
+               dev_name(&win->dc->ndev->dev), win->out_y + win->out_h, yres);
+
+       if (((win->out_x + win->out_w) > xres) && (win->out_x < xres)) {
+               long new_w = xres - win->out_x;
+               win->w = win->w * new_w / win->out_w;
+               win->out_w = new_w;
+       }
+       if (((win->out_y + win->out_h) > yres) && (win->out_y < yres)) {
+               long new_h = yres - win->out_y;
+               win->h = win->h * new_h / win->out_h;
+               win->out_h = new_h;
        }
 
        win->z = flip_win->attr.z;