summaryrefslogtreecommitdiffstats
path: root/hwc/hwc.c
diff options
context:
space:
mode:
authorLajos Molnar <molnar@ti.com>2011-12-08 14:57:30 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2011-12-08 14:57:30 -0800
commitf58db2d6fdddb67953bcb63f6c1edb7589b06a09 (patch)
tree8422dbb2b7ec364ff489c19f7d772679f2679e5a /hwc/hwc.c
parent396df5ae6a9c4d0204ceeaec1849355474058361 (diff)
parente14d52936107e390e2464df1e6653efde5409096 (diff)
downloadhardware_ti_omap4xxx-f58db2d6fdddb67953bcb63f6c1edb7589b06a09.zip
hardware_ti_omap4xxx-f58db2d6fdddb67953bcb63f6c1edb7589b06a09.tar.gz
hardware_ti_omap4xxx-f58db2d6fdddb67953bcb63f6c1edb7589b06a09.tar.bz2
am e14d5293: hwc: extract HDMI mode scoring function
* commit 'e14d52936107e390e2464df1e6653efde5409096': hwc: extract HDMI mode scoring function
Diffstat (limited to 'hwc/hwc.c')
-rw-r--r--hwc/hwc.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/hwc/hwc.c b/hwc/hwc.c
index 95dc9fe..c894b9a 100644
--- a/hwc/hwc.c
+++ b/hwc/hwc.c
@@ -768,6 +768,44 @@ static int omap4_hwc_is_valid_layer(omap4_hwc_device_t *hwc_dev,
return omap4_hwc_can_scale_layer(hwc_dev, layer, handle);
}
+static __u32 add_scaling_score(__u32 score,
+ __u32 xres, __u32 yres, __u32 refresh,
+ __u32 ext_xres, __u32 ext_yres,
+ __u32 mode_xres, __u32 mode_yres, __u32 mode_refresh)
+{
+ __u32 area = xres * yres;
+ __u32 ext_area = ext_xres * ext_yres;
+ __u32 mode_area = mode_xres * mode_yres;
+
+ /* prefer to upscale (1% tolerance) [0..1] (insert after 1st bit) */
+ int upscale = (ext_xres >= xres * 99 / 100 && ext_yres >= yres * 99 / 100);
+ score = (((score & ~1) | upscale) << 1) | (score & 1);
+
+ /* pick minimum scaling [0..16] */
+ if (ext_area > area)
+ score = (score << 5) | (16 * area / ext_area);
+ else
+ score = (score << 5) | (16 * ext_area / area);
+
+ /* pick smallest leftover area [0..16] */
+ score = (score << 5) | ((16 * ext_area + (mode_area >> 1)) / mode_area);
+
+ /* adjust mode refresh rate */
+ mode_refresh += mode_refresh % 6 == 5;
+
+ /* prefer same or higher frame rate */
+ upscale = (mode_refresh >= refresh);
+ score = (score << 1) | upscale;
+
+ /* pick closest frame rate */
+ if (mode_refresh > refresh)
+ score = (score << 8) | (240 * refresh / mode_refresh);
+ else
+ score = (score << 8) | (240 * mode_refresh / refresh);
+
+ return score;
+}
+
static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres, __u32 yres,
float xpy)
{
@@ -801,8 +839,8 @@ static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres,
__u32 ext_fb_xres, ext_fb_yres;
for (i = 0; i < d.dis.modedb_len; i++) {
__u32 score = 0;
- __u32 area = xres * yres;
- __u32 mode_area = d.modedb[i].xres * d.modedb[i].yres;
+ __u32 mode_xres = d.modedb[i].xres;
+ __u32 mode_yres = d.modedb[i].yres;
__u32 ext_width = d.dis.width_in_mm;
__u32 ext_height = d.dis.height_in_mm;
@@ -814,10 +852,10 @@ static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres,
ext_height = 9;
}
- if (mode_area == 0)
+ if (!mode_xres || !mode_yres)
continue;
- get_max_dimensions(xres, yres, xpy, d.modedb[i].xres, d.modedb[i].yres,
+ get_max_dimensions(xres, yres, xpy, mode_xres, mode_yres,
ext_width, ext_height, &ext_fb_xres, &ext_fb_yres);
/* we need to ensure that even TILER2D buffers can be scaled */
@@ -832,33 +870,20 @@ static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres,
if (d.modedb[i].flag & (FB_FLAG_RATIO_4_3 | FB_FLAG_RATIO_16_9))
score = 1;
- /* prefer to upscale (1% tolerance) */
- __u32 upscaling = (ext_fb_xres >= xres * 99 / 100 && ext_fb_yres >= yres * 99 / 100);
- score = (score << 1) | upscaling;
-
/* prefer the same mode as we use for mirroring to avoid mode change */
- score = (score << 1) | (i == ~ext->mirror_mode && ext->avoid_mode_change);
-
- /* pick closest screen size */
- if (ext_fb_xres * ext_fb_yres > area)
- score = (score << 5) | (16 * area / ext_fb_xres / ext_fb_yres);
- else
- score = (score << 5) | (16 * ext_fb_xres * ext_fb_yres / area);
-
- /* pick smallest leftover area */
- score = (score << 5) | ((16 * ext_fb_xres * ext_fb_yres + (mode_area >> 1)) / mode_area);
+ score = (score << 1) | (i == ~ext->mirror_mode && ext->avoid_mode_change);
- /* pick highest frame rate */
- score = (score << 8) | d.modedb[i].refresh;
+ score = add_scaling_score(score, xres, yres, 60, ext_fb_xres, ext_fb_yres,
+ mode_xres, mode_yres, d.modedb[i].refresh ? : 1);
- LOGD("#%d: %dx%d %dHz", i, d.modedb[i].xres, d.modedb[i].yres, d.modedb[i].refresh);
+ LOGD("#%d: %dx%d %dHz", i, mode_xres, mode_yres, d.modedb[i].refresh);
if (debug)
- LOGD(" score=%u adj.res=%dx%d", score, ext_fb_xres, ext_fb_yres);
+ LOGD(" score=0x%x adj.res=%dx%d", score, ext_fb_xres, ext_fb_yres);
if (best_score < score) {
ext->width = ext_width;
ext->height = ext_height;
- ext->xres = d.modedb[i].xres;
- ext->yres = d.modedb[i].yres;
+ ext->xres = mode_xres;
+ ext->yres = mode_yres;
best = i;
best_score = score;
}