Stolen from the intel ddx driver, see:
https://cgit.freedesktop.org/xorg/driver/xf86-video-intel/commit/?id=26fd6bec
https://bugs.freedesktop.org/show_bug.cgi?id=37858

it makes those common modes selectable when using the modesetting driver.

Signed-off-by: Adel Gadllah <[email protected]>
---
 hw/xfree86/drivers/modesetting/drmmode_display.c | 107 ++++++++++++++++++++++-
 1 file changed, 106 insertions(+), 1 deletion(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c 
b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 0d34ca1..078b497 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -953,6 +953,111 @@ has_panel_fitter(xf86OutputPtr output)
     return FALSE;
 }
 
+static struct pixel_count {
+       int16_t width, height;
+} common_16_9[] = {
+       { 640, 360 },
+       { 720, 405 },
+       { 864, 486 },
+       { 960, 540 },
+       { 1024, 576 },
+       { 1280, 720 },
+       { 1366, 768 },
+       { 1600, 900 },
+       { 1920, 1080 },
+       { 2048, 1152 },
+       { 2560, 1440 },
+       { 2880, 1620 },
+       { 3200, 1800 },
+       { 3840, 2160 },
+       { 4096, 2304 },
+       { 5120, 2880 },
+       { 7680, 4320 },
+       { 15360, 8640 },
+}, common_16_10[] = {
+       { 1280, 800 },
+       { 1400, 900 },
+       { 1680, 1050 },
+       { 1920, 1200 },
+       { 2560, 1600 },
+};
+
+static bool
+drmmode_output_is_duplicate_mode(DisplayModePtr modes, DisplayModePtr m)
+{
+       if (m == NULL)
+               return false;
+
+       while (modes) {
+               if (xf86ModesEqual(modes, m))
+                       return true;
+
+               modes = modes->next;
+       }
+
+       return false;
+}
+
+static DisplayModePtr
+drmmode_output_get_default_modes(DisplayModePtr preferred)
+{
+    DisplayModePtr modes;
+    int n;
+
+    modes = xf86GetDefaultModes();
+    if (preferred) {
+               DisplayModePtr m;
+
+               /* Add a half-resolution mode useful for large panels */
+               m = xf86GTFMode(preferred->HDisplay / 2,
+                               preferred->VDisplay / 2,
+                               xf86ModeVRefresh(preferred),
+                               FALSE, FALSE);
+               if (!drmmode_output_is_duplicate_mode(modes, m))
+                       modes = xf86ModesAdd(modes, m);
+               else
+                       free(m);
+
+               if (preferred->VDisplay * 16 > preferred->HDisplay * 9 - 
preferred->HDisplay / 32 &&
+                   preferred->VDisplay * 16 < preferred->HDisplay * 9 + 
preferred->HDisplay / 32) {
+                       for (n = 0; n < ARRAY_SIZE(common_16_9); n++) {
+                               if (preferred->HDisplay <= common_16_9[n].width 
||
+                                   preferred->VDisplay <= 
common_16_9[n].height)
+                                       break;
+
+                               m = xf86GTFMode(common_16_9[n].width,
+                                               common_16_9[n].height,
+                                               xf86ModeVRefresh(preferred),
+                                               FALSE, FALSE);
+                               if (!drmmode_output_is_duplicate_mode(modes, m))
+                                       modes = xf86ModesAdd(modes, m);
+                               else
+                                       free(m);
+                       }
+               }
+
+               if (preferred->VDisplay * 16 > preferred->HDisplay * 10 - 
preferred->HDisplay / 32 &&
+                   preferred->VDisplay * 16 < preferred->HDisplay * 10 + 
preferred->HDisplay / 32) {
+                       for (n = 0; n < ARRAY_SIZE(common_16_10); n++) {
+                               if (preferred->HDisplay <= 
common_16_10[n].width ||
+                                   preferred->VDisplay <= 
common_16_10[n].height)
+                                       break;
+
+                               m = xf86GTFMode(common_16_10[n].width,
+                                               common_16_10[n].height,
+                                               xf86ModeVRefresh(preferred),
+                                               FALSE, FALSE);
+                               if (!drmmode_output_is_duplicate_mode(modes, m))
+                                       modes = xf86ModesAdd(modes, m);
+                               else
+                                       free(m);
+                       }
+               }
+       }
+
+       return modes;
+}
+
 static DisplayModePtr
 drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes)
 {
@@ -978,7 +1083,7 @@ drmmode_output_add_gtf_modes(xf86OutputPtr output, 
DisplayModePtr Modes)
     max_vrefresh = max(max_vrefresh, 60.0);
     max_vrefresh *= (1 + SYNC_TOLERANCE);
 
-    m = xf86GetDefaultModes();
+    m = drmmode_output_get_default_modes();
     xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0);
 
     for (i = m; i; i = i->next) {
-- 
2.5.0

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to