@@ -26,6 +26,7 @@ namespace
2626{
2727
2828const char * SETTING_VIDEOSCREEN_WHITELIST_PULLDOWN {" videoscreen.whitelistpulldown" };
29+ const char * SETTING_VIDEOSCREEN_WHITELIST_WHOLENUMBER {" videoscreen.whitelistwholenumber" };
2930const char * SETTING_VIDEOSCREEN_WHITELIST_DOUBLEREFRESHRATE {
3031 " videoscreen.whitelistdoublerefreshrate" };
3132
@@ -133,41 +134,10 @@ void CResolutionUtils::FindResolutionFromWhitelist(float fps, int width, int hei
133134 }
134135 }
135136
136- CLog::Log (LOGDEBUG , " [WHITELIST] Searching for an exact resolution with an exact refresh rate" );
137-
138137 unsigned int penalty = std::numeric_limits<unsigned int >::max ();
139138 bool found = false ;
140139
141- for (const auto & mode : indexList)
142- {
143- auto i = CDisplaySettings::GetInstance ().GetResFromString (mode.asString ());
144- const RESOLUTION_INFO info = CServiceBroker::GetWinSystem ()->GetGfxContext ().GetResInfo (i);
145-
146- // allow resolutions that are exact and have the correct refresh rate
147- // allow hardware decoder surface padding due to codec block alignment and GPU requirements
148- // note: height has greater tolerance due to 32/64px boundaries e.g. 1080→1088 or 2160→2176
149- if (((height == info.iScreenHeight && width <= info.iScreenWidth + 8 ) ||
150- (width == info.iScreenWidth && height <= info.iScreenHeight + 32 )) &&
151- (info.dwFlags & dwFlags) == dwFlags &&
152- MathUtils::FloatEquals (info.fRefreshRate , fps, 0 .01f ))
153- {
154- CLog::Log (LOGDEBUG ,
155- " [WHITELIST] Matched an exact resolution with an exact refresh rate {}, 0x{:x} ({})" ,
156- info.strMode , info.dwFlags , i);
157- unsigned int pen = abs (info.iScreenHeight - height) + abs (info.iScreenWidth - width);
158- if (pen < penalty)
159- {
160- resolution = i;
161- found = true ;
162- penalty = pen;
163- }
164- }
165- }
166-
167- if (!found)
168- CLog::Log (LOGDEBUG , " [WHITELIST] No match for an exact resolution with an exact refresh rate" );
169-
170- if (noWhiteList || CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
140+ if (CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
171141 SETTING_VIDEOSCREEN_WHITELIST_DOUBLEREFRESHRATE ))
172142 {
173143 CLog::Log (LOGDEBUG ,
@@ -204,10 +174,79 @@ void CResolutionUtils::FindResolutionFromWhitelist(float fps, int width, int hei
204174 CLog::Log (LOGDEBUG ,
205175 " [WHITELIST] No match for an exact resolution with double the refresh rate" );
206176 }
207- else if (found)
177+
178+ if (CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
179+ SETTING_VIDEOSCREEN_WHITELIST_WHOLENUMBER ))
180+ {
181+ CLog::Log (LOGDEBUG ,
182+ " [WHITELIST] Searching for an exact resolution with a whole-number repeat refresh rate" );
183+
184+ for (const auto & mode : indexList)
185+ {
186+ auto i = CDisplaySettings::GetInstance ().GetResFromString (mode.asString ());
187+ const RESOLUTION_INFO info = CServiceBroker::GetWinSystem ()->GetGfxContext ().GetResInfo (i);
188+
189+ // allow resolutions that are exact and have 5 times the refresh rate
190+ // allow hardware decoder surface padding due to codec block alignment and GPU requirements
191+ if (((height == info.iScreenHeight && width <= info.iScreenWidth + 8 ) ||
192+ (width == info.iScreenWidth && height <= info.iScreenHeight + 32 )) &&
193+ (info.dwFlags & dwFlags) == dwFlags &&
194+ (MathUtils::FloatEquals (info.fRefreshRate , fps * 4 .0f , 0 .01f ) ||
195+ MathUtils::FloatEquals (info.fRefreshRate , fps * 5 .0f , 0 .01f )))
196+ {
197+ CLog::Log (
198+ LOGDEBUG ,
199+ " [WHITELIST] Matched an exact resolution with a whole-number repeat refresh rate {} ({})" ,
200+ info.strMode , i);
201+ unsigned int pen = abs (info.iScreenHeight - height) + abs (info.iScreenWidth - width);
202+ if (pen < penalty)
203+ {
204+ resolution = i;
205+ found = true ;
206+ penalty = pen;
207+ }
208+ }
209+ }
210+ if (found)
211+ return ;
212+
213+ CLog::Log (LOGDEBUG , " [WHITELIST] No match for a resolution with a whole-number repeat refresh rate" );
214+ }
215+
216+ CLog::Log (LOGDEBUG , " [WHITELIST] Searching for an exact resolution with an exact refresh rate" );
217+
218+ for (const auto & mode : indexList)
219+ {
220+ auto i = CDisplaySettings::GetInstance ().GetResFromString (mode.asString ());
221+ const RESOLUTION_INFO info = CServiceBroker::GetWinSystem ()->GetGfxContext ().GetResInfo (i);
222+
223+ // allow resolutions that are exact and have the correct refresh rate
224+ // allow hardware decoder surface padding due to codec block alignment and GPU requirements
225+ // note: height has greater tolerance due to 32/64px boundaries e.g. 1080→1088 or 2160→2176
226+ if (((height == info.iScreenHeight && width <= info.iScreenWidth + 8 ) ||
227+ (width == info.iScreenWidth && height <= info.iScreenHeight + 32 )) &&
228+ (info.dwFlags & dwFlags) == dwFlags &&
229+ MathUtils::FloatEquals (info.fRefreshRate , fps, 0 .01f ))
230+ {
231+ CLog::Log (LOGDEBUG ,
232+ " [WHITELIST] Matched an exact resolution with an exact refresh rate {}, 0x{:x} ({})" ,
233+ info.strMode , info.dwFlags , i);
234+ unsigned int pen = abs (info.iScreenHeight - height) + abs (info.iScreenWidth - width);
235+ if (pen < penalty)
236+ {
237+ resolution = i;
238+ found = true ;
239+ penalty = pen;
240+ }
241+ }
242+ }
243+
244+ if (!found)
245+ CLog::Log (LOGDEBUG , " [WHITELIST] No match for an exact resolution with an exact refresh rate" );
246+ else
208247 return ;
209248
210- if (noWhiteList || CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
249+ if (CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
211250 SETTING_VIDEOSCREEN_WHITELIST_PULLDOWN ))
212251 {
213252 CLog::Log (LOGDEBUG ,
@@ -270,8 +309,10 @@ void CResolutionUtils::FindResolutionFromWhitelist(float fps, int width, int hei
270309 }
271310 if (!found)
272311 CLog::Log (LOGDEBUG , " [WHITELIST] No match for a closest resolution with an exact refresh rate" );
312+ else
313+ return ;
273314
274- if (noWhiteList || CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
315+ if (CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
275316 SETTING_VIDEOSCREEN_WHITELIST_DOUBLEREFRESHRATE ))
276317 {
277318 CLog::Log (LOGDEBUG , " [WHITELIST] Searching for a closest resolution with double refresh rate" );
@@ -302,8 +343,6 @@ void CResolutionUtils::FindResolutionFromWhitelist(float fps, int width, int hei
302343
303344 CLog::Log (LOGDEBUG , " [WHITELIST] No match for a closest resolution with double refresh rate" );
304345 }
305- else if (found)
306- return ;
307346
308347 CLog::Log (LOGDEBUG , " [WHITELIST] Searching for a desktop resolution with an exact refresh rate" );
309348
@@ -327,7 +366,7 @@ void CResolutionUtils::FindResolutionFromWhitelist(float fps, int width, int hei
327366
328367 CLog::Log (LOGDEBUG , " [WHITELIST] No match for a desktop resolution with an exact refresh rate" );
329368
330- if (noWhiteList || CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
369+ if (CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
331370 SETTING_VIDEOSCREEN_WHITELIST_DOUBLEREFRESHRATE ))
332371 {
333372 CLog::Log (LOGDEBUG ,
@@ -355,7 +394,7 @@ void CResolutionUtils::FindResolutionFromWhitelist(float fps, int width, int hei
355394 " [WHITELIST] No match for a desktop resolution with double the refresh rate" );
356395 }
357396
358- if (noWhiteList || CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
397+ if (CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
359398 SETTING_VIDEOSCREEN_WHITELIST_PULLDOWN ))
360399 {
361400 CLog::Log (LOGDEBUG ,
@@ -384,6 +423,36 @@ void CResolutionUtils::FindResolutionFromWhitelist(float fps, int width, int hei
384423 " [WHITELIST] No match for a desktop resolution with a 3:2 pulldown refresh rate" );
385424 }
386425
426+ if (CServiceBroker::GetSettingsComponent ()->GetSettings ()->GetBool (
427+ SETTING_VIDEOSCREEN_WHITELIST_WHOLENUMBER ))
428+ {
429+ CLog::Log (LOGDEBUG ,
430+ " [WHITELIST] Searching for a desktop resolution with a whole-number repeat refresh rate" );
431+
432+ for (const auto & mode : indexList)
433+ {
434+ auto i = CDisplaySettings::GetInstance ().GetResFromString (mode.asString ());
435+ const RESOLUTION_INFO info = CServiceBroker::GetWinSystem ()->GetGfxContext ().GetResInfo (i);
436+
437+ // allow resolutions that are desktop resolution but have whole-number refresh rate
438+ if (info.iScreenWidth == desktop_info.iScreenWidth &&
439+ (info.dwFlags & dwFlags) == dwFlags &&
440+ (MathUtils::FloatEquals (info.fRefreshRate , fps * 4 .0f , 0 .01f ) ||
441+ MathUtils::FloatEquals (info.fRefreshRate , fps * 5 .0f , 0 .01f )))
442+ {
443+ CLog::Log (
444+ LOGDEBUG ,
445+ " [WHITELIST] Matched a desktop resolution with a whole-number repeat refresh rate {} ({})" ,
446+ info.strMode , i);
447+ resolution = i;
448+ return ;
449+ }
450+ }
451+
452+ CLog::Log (LOGDEBUG ,
453+ " [WHITELIST] No match for a desktop resolution with a whole-number repeat refresh rate" );
454+ }
455+
387456 if (is3D && curr.fRefreshRate > 30 )
388457 {
389458 CLog::Log (LOGDEBUG , " [WHITELIST] No resolution matched but refresh rate is {:0.3f}" , curr.fRefreshRate );
0 commit comments