MythTV master
mythdisplaydrm.cpp
Go to the documentation of this file.
1// MythTV
4#include "mythmainwindow.h"
7
8#define LOC QString("DispDRM: ")
9
11{
12#if CONFIG_QTPRIVATEHEADERS
13 if (m_device)
14 m_device->MainWindowReady();
15#endif
16}
17
19{
20#if CONFIG_QTPRIVATEHEADERS
21 if (!HasMythMainWindow())
22 return false;
23
24 if (auto *mainwindow = GetMythMainWindow(); mainwindow)
25 {
26 if (auto *drmdisplay = dynamic_cast<MythDisplayDRM*>(mainwindow->GetDisplay()); drmdisplay)
27 {
28 if (auto drm = drmdisplay->GetDevice(); drm && drm->Atomic() && drm->Authenticated())
29 {
30 if (auto plane = drm->GetVideoPlane(); plane && plane->m_id)
31 return true;
32 }
33 }
34 }
35#endif
36 return false;
37}
38
40{
42 Initialise();
43#if CONFIG_QTPRIVATEHEADERS
44 if (MainWindow && m_device && m_device->GetVideoPlane())
46#endif
47}
48
50{
51 m_device = nullptr;
52}
53
55{
56 return m_device;
57}
58
59// FIXME - I doubt this slot is being called correctly but the screen won't
60// change if we are using a fullscreen platform plugin (e.g. eglfs)
61void MythDisplayDRM::ScreenChanged(QScreen *qScreen)
62{
64
65 if (m_device && m_device->GetScreen() != m_screen)
66 m_device = nullptr;
67
68 if (!m_device)
70
71 emit screenChanged();
72}
73
75{
76 return m_device && m_device->CanSwitchModes();
77}
78
80{
81#if CONFIG_QTPRIVATEHEADERS
82 return m_device && m_device->Authenticated() && m_device->Atomic() &&
83 m_device->GetVideoPlane() && m_device->GetVideoPlane()->m_id;
84#else
85 return false;
86#endif
87}
88
90{
91 if (gCoreContext && m_device && m_device->CanSwitchModes())
92 return gCoreContext->GetBoolSetting("UseVideoModes", false);
93 return false;
94}
95
97{
98 if (m_device)
99 {
100 // Ensure video modes are fetched early
102 m_refreshRate = m_device->GetRefreshRate();
103 m_resolution = m_device->GetResolution();
104 m_physicalSize = m_device->GetPhysicalSize();
105 m_edid = m_device->GetEDID();
106 m_modeComplete = true;
107 return;
108 }
110}
111
113{
114 if (!m_videoModes.empty())
115 return m_videoModes;
116
117 m_videoModes.clear();
118 m_modeMap.clear();
119 if (!m_screen || !m_device || !m_device->CanSwitchModes())
120 return m_videoModes;
121
122 auto mainresolution = m_device->GetResolution();
123 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Filtering out modes that aren't %1x%2")
124 .arg(mainresolution.width()).arg(mainresolution.height()));
125
126 DisplayModeMap screenmap;
127 auto modes = m_device->GetModes();
128 auto physicalsize = m_device->GetPhysicalSize();
129 for (const auto & mode : modes)
130 {
131 auto width = mode->m_width;
132 auto height = mode->m_height;
133 auto rate = mode->m_rate;
134
135 // Filter out interlaced modes
136 if ((mode->m_flags & DRM_MODE_FLAG_INTERLACE) != 0U)
137 {
138 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Ignoring interlaced mode %1x%2 %3i")
139 .arg(width).arg(height).arg(rate, 2, 'f', 2, '0'));
140 continue;
141 }
142
143 // Filter out anything that is not the same size as our current screen
144 // i.e. refresh rate changes only
145 if (auto size = QSize(width, height); size != mainresolution)
146 {
147 LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Ignoring mode %1x%2 %3")
148 .arg(width).arg(height).arg(rate, 2, 'f', 2, '0'));
149 continue;
150 }
151
152 QSize resolution(width, height);
153 auto key = MythDisplayMode::CalcKey(resolution, 0.0);
154 if (screenmap.find(key) == screenmap.end())
155 screenmap[key] = MythDisplayMode(resolution, physicalsize, -1.0, rate);
156 else
157 screenmap[key].AddRefreshRate(rate);
158 m_modeMap.insert(MythDisplayMode::CalcKey(resolution, rate), mode->m_index);
159 }
160
161 for (auto & it : screenmap)
162 m_videoModes.push_back(it.second);
163
164 DebugModes();
165 return m_videoModes;
166}
167
168bool MythDisplayDRM::SwitchToVideoMode(QSize Size, double DesiredRate)
169{
170 if (!m_screen || !m_device || !m_device->CanSwitchModes() || m_videoModes.empty())
171 return false;
172
173 auto rate = static_cast<double>(NAN);
174 QSize dummy(0, 0);
175 MythDisplayMode desired(Size, dummy, -1.0, DesiredRate);
176 int index = MythDisplayMode::FindBestMatch(m_videoModes, desired, rate);
177
178 if (index < 0)
179 {
180 LOG(VB_GENERAL, LOG_ERR, LOC + "Desired resolution and frame rate not found.");
181 return false;
182 }
183
184 auto mode = MythDisplayMode::CalcKey(Size, rate);
185 if (!m_modeMap.contains(mode))
186 {
187 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find mode");
188 return false;
189 }
190
191 return m_device->SwitchMode(m_modeMap.value(mode));
192}
bool GetBoolSetting(const QString &key, bool defaultval=false)
static MythDRMPtr Create(QScreen *qScreen, const QString &Device=QString(), bool NeedPlanes=true)
Create a MythDRMDevice instance.
void UpdateCurrentMode() override
Retrieve screen details.
MythDisplayDRM(MythMainWindow *MainWindow)
~MythDisplayDRM() override
bool VideoModesAvailable() override
MythDRMPtr m_device
const MythDisplayModes & GetVideoModes() override
bool SwitchToVideoMode(QSize Size, double DesiredRate) override
void screenChanged()
MythDRMPtr GetDevice()
static bool DirectRenderingAvailable()
bool UsingVideoModes() override
QMap< uint64_t, int > m_modeMap
void ScreenChanged(QScreen *qScreen) override
bool IsPlanar() override
static int FindBestMatch(const MythDisplayModes &Modes, const MythDisplayMode &Mode, double &TargetRate)
static uint64_t CalcKey(QSize Size, double Rate)
QSize m_resolution
Definition: mythdisplay.h:92
virtual void UpdateCurrentMode()
Retrieve screen details.
QSize m_physicalSize
Definition: mythdisplay.h:93
void Initialise()
double m_refreshRate
Definition: mythdisplay.h:90
virtual void ScreenChanged(QScreen *qScreen)
The actual screen in use has changed. We must use it.
MythDisplayModes m_videoModes
Definition: mythdisplay.h:98
QScreen * m_screen
Definition: mythdisplay.h:97
MythEDID m_edid
Definition: mythdisplay.h:94
bool m_modeComplete
Definition: mythdisplay.h:89
void DebugModes() const
void SignalWindowReady()
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOC
std::map< uint64_t, MythDisplayMode > DisplayModeMap
std::vector< MythDisplayMode > MythDisplayModes
#define DRM_MODE_FLAG_INTERLACE
std::shared_ptr< class MythDRMDevice > MythDRMPtr
Definition: mythdrmdevice.h:19
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
bool HasMythMainWindow(void)
MythMainWindow * GetMythMainWindow(void)