Improve mode finding
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 29 Sep 2016 07:55:19 +0000 (10:55 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 29 Sep 2016 08:21:20 +0000 (11:21 +0300)
Change calculated_vrefresh to round to 2 decimals, and do two rounds
when looking for a mode: first look for exact vrefresh match, then look
for rounded match.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
kms++/src/connector.cpp
kms++/src/modedb.cpp
kms++/src/videomode.cpp

index 92700af0961440919fd7e0a43605cca9b6e2c69d..7c6c179ebff4616b22187aec14c3927688cfcce1 100644 (file)
@@ -132,7 +132,24 @@ Videomode Connector::get_mode(unsigned xres, unsigned yres, float vrefresh, bool
                if (ilace != m.interlace())
                        continue;
 
-               if (vrefresh && std::abs(m.calculated_vrefresh() - vrefresh) >= 0.001)
+               if (vrefresh && vrefresh != m.calculated_vrefresh())
+                       continue;
+
+               return m;
+       }
+
+       // If not found, do another round using rounded vrefresh
+
+       for (int i = 0; i < c->count_modes; i++) {
+               Videomode m = drm_mode_to_video_mode(c->modes[i]);
+
+               if (m.hdisplay != xres || m.vdisplay != yres)
+                       continue;
+
+               if (ilace != m.interlace())
+                       continue;
+
+               if (vrefresh && vrefresh != roundf(m.calculated_vrefresh()))
                        continue;
 
                return m;
index 858c3d07f26ed428454d1d4499fdf65781d52340..5d5d373ba95ca64bd7aa01c947094280b13e3679 100644 (file)
@@ -20,7 +20,24 @@ static const Videomode& find_from_table(const Videomode* modes, uint32_t width,
                if (ilace != m.interlace())
                        continue;
 
-               if (vrefresh && std::abs(m.calculated_vrefresh() - vrefresh) >= 0.001)
+               if (vrefresh && vrefresh != m.calculated_vrefresh())
+                       continue;
+
+               return m;
+       }
+
+       // If not found, do another round using rounded vrefresh
+
+       for (unsigned i = 0; modes[i].clock; ++i) {
+               const Videomode& m = modes[i];
+
+               if (m.hdisplay != width || m.vdisplay != height)
+                       continue;
+
+               if (ilace != m.interlace())
+                       continue;
+
+               if (vrefresh && vrefresh != roundf(m.calculated_vrefresh()))
                        continue;
 
                return m;
index 107ee3bff9ceadba5707522c2a03adfdeb02c819..f675914c0660f11b568816842fdcb54f0ae11227 100644 (file)
@@ -1,5 +1,6 @@
 #include <xf86drm.h>
 #include <xf86drmMode.h>
+#include <math.h>
 
 #include <kms++/kms++.h>
 #include "helpers.h"
@@ -18,7 +19,8 @@ unique_ptr<Blob> Videomode::to_blob(Card& card) const
 
 float Videomode::calculated_vrefresh() const
 {
-       return (clock * 1000.0) / (htotal * vtotal) * (interlace() ? 2 : 1);
+       float refresh = (clock * 1000.0) / (htotal * vtotal) * (interlace() ? 2 : 1);
+       return roundf(refresh * 100.0) / 100.0;
 }
 
 bool Videomode::interlace() const