mirror of
https://github.com/jellyfin/jellyfin-desktop.git
synced 2026-10-26 16:45:24 +00:00
230 lines
6.5 KiB
C++
230 lines
6.5 KiB
C++
#include <QtTest/QtTest>
|
|
#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"
|