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