diff options
author | Lajos Molnar <molnar@ti.com> | 2011-12-08 14:57:30 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2011-12-08 14:57:30 -0800 |
commit | f58db2d6fdddb67953bcb63f6c1edb7589b06a09 (patch) | |
tree | 8422dbb2b7ec364ff489c19f7d772679f2679e5a /hwc/hwc.c | |
parent | 396df5ae6a9c4d0204ceeaec1849355474058361 (diff) | |
parent | e14d52936107e390e2464df1e6653efde5409096 (diff) | |
download | hardware_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.c | 73 |
1 files changed, 49 insertions, 24 deletions
@@ -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; } |