summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <lajos@ti.com>2012-05-07 16:42:31 -0500
committerErik Gilling <konkers@android.com>2012-05-21 13:37:50 -0700
commit16b7f6c4b06ac7350c30309d0559a466097d8ae7 (patch)
treea9aab1b86cd8aecb97e8e501b0f775e9452705fc
parent4495a87138cd1f0fdf62a9c4649e2c2bdbd3527d (diff)
downloadhardware_ti_omap4xxx-16b7f6c4b06ac7350c30309d0559a466097d8ae7.zip
hardware_ti_omap4xxx-16b7f6c4b06ac7350c30309d0559a466097d8ae7.tar.gz
hardware_ti_omap4xxx-16b7f6c4b06ac7350c30309d0559a466097d8ae7.tar.bz2
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>
-rw-r--r--hwc/hwc.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/hwc/hwc.c b/hwc/hwc.c
index b5b80ec..d6c28f7 100644
--- a/hwc/hwc.c
+++ b/hwc/hwc.c
@@ -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;