#include #include "../src/display/DisplayManager.h" #include "../src/settings/SettingsComponent.h" #include "../src/settings/SettingsSection.h" #include "../src/settings/SettingsValue.h" // Implements the pure virtuals (and some helpers) to test DisplayManager logic. class TestableDisplayManager : public DisplayManager { public: explicit TestableDisplayManager() : DisplayManager(nullptr), m_currentMode(0) {} bool setDisplayMode(int, int) override { return true; } int getCurrentDisplayMode(int) override { return m_currentMode; } int getMainDisplay() override { return 0; } int getDisplayFromPoint(int, int) override { return 0; } void setCurrentMode(int mode) { m_currentMode = mode; } void addMode(int id, int w, int h, int bpp, float hz, bool interlaced) { auto mode = DMVideoModePtr::create(); mode->m_id = id; mode->m_width = w; mode->m_height = h; mode->m_bitsPerPixel = bpp; mode->m_refreshRate = hz; mode->m_interlaced = interlaced; mode->m_privId = id; if (!m_displays.contains(0)) { auto disp = DMDisplayPtr::create(); disp->m_id = 0; disp->m_name = "TestDisplay"; disp->m_privId = 0; m_displays[0] = disp; } m_displays[0]->m_videoModes[id] = mode; } private: int m_currentMode; }; class TestDisplayManager : public QObject { Q_OBJECT private: void setAvoid25_30(bool on) { auto* section = SettingsComponent::Get().getSection(SETTINGS_SECTION_VIDEO); section->setValue("refreshrate.avoid_25hz_30hz", on); } private slots: void initTestCase(); void testExactRefreshRateMatch(); void testPrefers60HzOver30HzForFilm(); void testCloseRefreshRateMatch(); void testNoMatchWithDifferentResolution(); void testInterlacedPreference(); void testCurrentModeBonusBreaksTie(); void testAvoid25And30Hz(); void testNoSuitableModeReturnsNegative(); void testFindBestMode(); void testMultipleRefreshRate(); }; // Helper function: Populates a DisplayManager with some typical display modes. static void setupStandardModes(TestableDisplayManager& mgr) { // id, w, h, bpp, hz, interlaced mgr.addMode(0, 1920, 1080, 32, 24.0f, false); mgr.addMode(1, 1920, 1080, 32, 30.0f, false); mgr.addMode(2, 1920, 1080, 32, 50.0f, false); mgr.addMode(3, 1920, 1080, 32, 60.0f, false); // This will be set as currentMode (see below) mgr.addMode(4, 1920, 1080, 32, 23.976f, false); mgr.addMode(5, 1920, 1080, 32, 59.94f, false); mgr.setCurrentMode(3); } void TestDisplayManager::initTestCase() { auto* section = new SettingsSection(SETTINGS_SECTION_VIDEO, PLATFORM_ANY, -1, &SettingsComponent::Get()); auto* avoidSetting = new SettingsValue("refreshrate.avoid_25hz_30hz", false, PLATFORM_ANY, section); section->registerSetting(avoidSetting); SettingsComponent::Get().registerSection(section); } void TestDisplayManager::testExactRefreshRateMatch() { TestableDisplayManager mgr; setupStandardModes(mgr); DMMatchMediaInfo match(24.0f, false); int best = mgr.findBestMatch(0, match); QCOMPARE(best, 0); // 24 hz mode } void TestDisplayManager::testPrefers60HzOver30HzForFilm() { // Prefer 60 hz for 30 fps content. TestableDisplayManager mgr; setupStandardModes(mgr); DMMatchMediaInfo match(30.0f, false); setAvoid25_30(true); int best = mgr.findBestMatch(0, match); QCOMPARE(best, 3); setAvoid25_30(false); } void TestDisplayManager::testCloseRefreshRateMatch() { // Prefer 24hz for 23.976 fps content. TestableDisplayManager mgr; setupStandardModes(mgr); DMMatchMediaInfo match(23.976f, false); int best = mgr.findBestMatch(0, match); QCOMPARE(best, 4); } void TestDisplayManager::testNoMatchWithDifferentResolution() { // Prefer 1080p over 720p, regardless of framerate. TestableDisplayManager mgr; mgr.addMode(0, 1920, 1080, 32, 60.0f, false); mgr.addMode(1, 1280, 720, 32, 24.0f, false); mgr.setCurrentMode(0); DMMatchMediaInfo match(24.0f, false); int best = mgr.findBestMatch(0, match); QCOMPARE(best, 0); } void TestDisplayManager::testInterlacedPreference() { // Prefer interlaced mode for interlaced content. TestableDisplayManager mgr; mgr.addMode(0, 1920, 1080, 32, 50.0f, false); mgr.addMode(1, 1920, 1080, 32, 50.0f, true); mgr.setCurrentMode(0); // non-interlaced DMMatchMediaInfo match(50.0f, true); int best = mgr.findBestMatch(0, match); QCOMPARE(best, 1); } void TestDisplayManager::testCurrentModeBonusBreaksTie() { // Prefer current mode when multiple identical modes available. TestableDisplayManager mgr; mgr.addMode(0, 1920, 1080, 32, 60.0f, false); mgr.addMode(1, 1920, 1080, 32, 60.0f, false); mgr.setCurrentMode(1); DMMatchMediaInfo match(60.0f, false); int best = mgr.findBestMatch(0, match); QCOMPARE(best, 1); } void TestDisplayManager::testAvoid25And30Hz() { // Prefer 50 hz for 25 fps content when avoid25_30 is enabled. TestableDisplayManager mgr; mgr.addMode(0, 1920, 1080, 32, 25.0f, false); mgr.addMode(1, 1920, 1080, 32, 50.0f, false); mgr.setCurrentMode(1); DMMatchMediaInfo match(25.0f, false); setAvoid25_30(true); int best = mgr.findBestMatch(0, match); QCOMPARE(best, 1); // Disabling avoid25_30 should produce the opposite result. setAvoid25_30(false); best = mgr.findBestMatch(0, match); QCOMPARE(best, 0); } void TestDisplayManager::testNoSuitableModeReturnsNegative() { // No preference when resolution doesn't match content. TestableDisplayManager mgr; mgr.addMode(0, 1920, 1080, 32, 60.0f, false); mgr.addMode(1, 1280, 720, 32, 24.0f, false); mgr.setCurrentMode(0); mgr.m_displays[0]->m_videoModes.remove(0); DMMatchMediaInfo match(24.0f, false); int best = mgr.findBestMatch(0, match); QCOMPARE(best, -1); } void TestDisplayManager::testFindBestMode() { // Prefer greatest refresh rate, greatest resolution, and non-interlaced. TestableDisplayManager mgr; mgr.addMode(0, 1280, 720, 32, 60.0f, false); mgr.addMode(1, 1920, 1080, 32, 60.0f, false); mgr.addMode(2, 1920, 1080, 32, 30.0f, true); mgr.addMode(3, 1920, 1080, 32, 60.0f, true); int best = mgr.findBestMode(0); QCOMPARE(best, 1); } void TestDisplayManager::testMultipleRefreshRate() { // Prefer exact multiple of fps rate. TestableDisplayManager mgr; mgr.addMode(0, 1920, 1080, 32, 47.952f, false); mgr.addMode(1, 1920, 1080, 32, 60.0f, false); mgr.setCurrentMode(1); DMMatchMediaInfo match(23.976f, false); int best = mgr.findBestMatch(0, match); QCOMPARE(best, 0); } QTEST_APPLESS_MAIN(TestDisplayManager) #include "test_displaymanager.moc"