diff options
author | Lajos Molnar <molnar@ti.com> | 2011-10-12 19:04:40 -0500 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-10-17 19:32:30 -0700 |
commit | 4e635e537afaa9f1416fa5bdbfd1b03afd8b7e6a (patch) | |
tree | 9780bc9a7fd519109706c065cf97e93134e5085d | |
parent | 4cb51e55fa79a592d50d94c0700660e42c988a0b (diff) | |
download | omap4xxx-omapzoom-4e635e537afaa9f1416fa5bdbfd1b03afd8b7e6a.tar.gz |
hwc: avoid changing HDMI modes
Prefer to use the same mode for docking as used for mirroring.
This avoids changing modes when playing low resolution videos, but
may produce worse quality on some TVs.
Added persist.hwc.avoid_mode_change property (default 1) so that
this behavior can be disabled.
Also, reworked mode scoring so that each term can be easily reordered.
Change-Id: Ie25aa4dba11d3922e510257e7a8e88d2379bb6d7
-rw-r--r-- | hwc/hwc.c | 27 |
1 files changed, 18 insertions, 9 deletions
@@ -72,6 +72,7 @@ struct omap4_hwc_ext { /* support */ struct ext_transform_t mirror; /* mirroring settings */ struct ext_transform_t dock; /* docking settings */ + __u8 avoid_mode_change; /* use HDMI mode used for mirroring if possible */ /* state */ __u8 on_tv; /* using a tv */ @@ -82,6 +83,7 @@ struct omap4_hwc_ext { __u32 last_xres_used; /* resolution and pixel ratio used for mode selection */ __u32 last_yres_used; __u32 last_mode; /* 2-s complement of last HDMI mode set, 0 if none */ + __u32 mirror_mode; /* 2-s complement of mode used when mirroring */ float last_xpy; __u16 width; /* external screen dimensions */ __u16 height; @@ -730,23 +732,26 @@ static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres, /* prefer CEA modes */ if (d.modedb[i].flag & (FB_FLAG_RATIO_4_3 | FB_FLAG_RATIO_16_9)) - score |= (1 << 30); + score = 1; /* prefer to upscale (1% tolerance) */ - if (ext_fb_xres >= xres * 99 / 100 && ext_fb_yres >= yres * 99 / 100) - score |= (1 << 29); + __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 |= (1 << 24) * (16 * area / ext_fb_xres / ext_fb_yres); + score = (score << 5) | (16 * area / ext_fb_xres / ext_fb_yres); else - score |= (1 << 24) * (16 * ext_fb_xres * ext_fb_yres / area); + score = (score << 5) | (16 * ext_fb_xres * ext_fb_yres / area); /* pick smallest leftover area */ - score |= (1 << 19) * ((16 * ext_fb_xres * ext_fb_yres + (mode_area >> 1)) / mode_area); + score = (score << 5) | ((16 * ext_fb_xres * ext_fb_yres + (mode_area >> 1)) / mode_area); /* pick highest frame rate */ - score |= (1 << 11) * d.modedb[i].refresh; + score = (score << 8) | d.modedb[i].refresh; LOGD("#%d: %dx%d %dHz", i, d.modedb[i].xres, d.modedb[i].yres, d.modedb[i].refresh); if (debug) @@ -1411,6 +1416,8 @@ static void handle_hotplug(omap4_hwc_device_t *hwc_dev, int state) ext->dock.enabled = atoi(value) > 0; property_get("persist.hwc.mirroring.enabled", value, "1"); ext->mirror.enabled = atoi(value) > 0; + property_get("persist.hwc.avoid_mode_change", value, "1"); + ext->avoid_mode_change = atoi(value) > 0; /* get cloning transformation */ property_get("persist.hwc.docking.transform", value, "0"); @@ -1428,10 +1435,12 @@ static void handle_hotplug(omap4_hwc_device_t *hwc_dev, int state) __u32 yres = HEIGHT(ext->mirror_region); if (ext->mirror.rotation & 1) swap(xres, yres); + ext->mirror_mode = 0; int res = omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, 1.); - if (!res) + if (!res) { + ext->mirror_mode = ext->last_mode; ioctl(hwc_dev->hdmi_fb_fd, FBIOBLANK, FB_BLANK_UNBLANK); - else + } else ext->mirror.enabled = 0; } } else { |