diff options
author | Lajos Molnar <lajos@ti.com> | 2012-05-07 16:42:31 -0500 |
---|---|---|
committer | Erik Gilling <konkers@android.com> | 2012-05-21 13:37:50 -0700 |
commit | 16b7f6c4b06ac7350c30309d0559a466097d8ae7 (patch) | |
tree | a9aab1b86cd8aecb97e8e501b0f775e9452705fc /hwc | |
parent | 4495a87138cd1f0fdf62a9c4649e2c2bdbd3527d (diff) | |
download | omap4xxx-omapzoom-16b7f6c4b06ac7350c30309d0559a466097d8ae7.tar.gz |
hwc: Fix truncation errors in scaling decision
When checking if we are downscaling beyond what the hardware
supports, we were dividing by the factors rather than multiplying
the other side with them. The truncation of the divisions had
hwc allowing downscaling by a factor slightly larger than what
was supported.
Change-Id: I6ae4d897f4afe68ae26f0d7385e4003d6f2a4253
Signed-off-by: Lajos Molnar <lajos@ti.com>
Diffstat (limited to 'hwc')
-rw-r--r-- | hwc/hwc.c | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -46,6 +46,8 @@ #define WIDTH(rect) ((rect).right - (rect).left) #define HEIGHT(rect) ((rect).bottom - (rect).top) +#define DIV_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) + #include <video/dsscomp.h> #include "hal_public.h" @@ -716,6 +718,8 @@ static int omap4_hwc_can_scale(__u32 src_w, __u32 src_h, __u32 dst_w, __u32 dst_ __u32 pclk) { __u32 fclk = limits->fclk / 1000; + __u32 min_src_w = DIV_ROUND_UP(src_w, is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d); + __u32 min_src_h = DIV_ROUND_UP(src_h, is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d); /* ERRATAs */ /* cannot render 1-width layers on DSI video mode panels - we just disallow all 1-width LCD layers */ @@ -729,15 +733,15 @@ static int omap4_hwc_can_scale(__u32 src_w, __u32 src_h, __u32 dst_w, __u32 dst_ return 0; /* max downscale */ - if (dst_h < src_h / limits->max_downscale / (is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d)) + if (dst_h * limits->max_downscale < min_src_h) return 0; /* for manual panels pclk is 0, and there are no pclk based scaling limits */ if (!pclk) - return (dst_w < src_w / limits->max_downscale / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d)); + return !(dst_w * limits->max_downscale < min_src_w); /* :HACK: limit horizontal downscale well below theoretical limit as we saw display artifacts */ - if (dst_w < src_w / 4) + if (dst_w * 4 < src_w) return 0; /* max horizontal downscale is 4, or the fclk/pixclk */ @@ -746,7 +750,7 @@ static int omap4_hwc_can_scale(__u32 src_w, __u32 src_h, __u32 dst_w, __u32 dst_ /* for small parts, we need to use integer fclk/pixclk */ if (src_w < limits->integer_scale_ratio_limit) fclk = fclk / pclk * pclk; - if ((__u32) dst_w < src_w * pclk / fclk / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d)) + if ((__u32) dst_w * fclk < min_src_w * pclk) return 0; return 1; |