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 
38 MythDisplayDRM::MythDisplayDRM([[maybe_unused]] MythMainWindow* MainWindow)
39 {
41  Initialise();
42 #ifdef USING_QTPRIVATEHEADERS
43  if (MainWindow && m_device && m_device->GetVideoPlane())
45 #endif
46 }
47 
49 {
50  m_device = nullptr;
51 }
52 
54 {
55  return m_device;
56 }
57 
58 // FIXME - I doubt this slot is being called correctly but the screen won't
59 // change if we are using a fullscreen platform plugin (e.g. eglfs)
60 void MythDisplayDRM::ScreenChanged(QScreen *qScreen)
61 {
63 
64  if (m_device && m_device->GetScreen() != m_screen)
65  m_device = nullptr;
66 
67  if (!m_device)
69 
70  emit screenChanged();
71 }
72 
74 {
75  return m_device && m_device->CanSwitchModes();
76 }
77 
79 {
80 #ifdef USING_QTPRIVATEHEADERS
81  return m_device && m_device->Authenticated() && m_device->Atomic() &&
82  m_device->GetVideoPlane() && m_device->GetVideoPlane()->m_id;
83 #else
84  return false;
85 #endif
86 }
87 
89 {
90  if (gCoreContext && m_device && m_device->CanSwitchModes())
91  return gCoreContext->GetBoolSetting("UseVideoModes", false);
92  return false;
93 }
94 
96 {
97  if (m_device)
98  {
99  // Ensure video modes are fetched early
100  GetVideoModes();
101  m_refreshRate = m_device->GetRefreshRate();
102  m_resolution = m_device->GetResolution();
103  m_physicalSize = m_device->GetPhysicalSize();
104  m_edid = m_device->GetEDID();
105  m_modeComplete = true;
106  return;
107  }
109 }
110 
112 {
113  if (!m_videoModes.empty())
114  return m_videoModes;
115 
116  m_videoModes.clear();
117  m_modeMap.clear();
118  if (!m_screen || !m_device || !m_device->CanSwitchModes())
119  return m_videoModes;
120 
121  auto mainresolution = m_device->GetResolution();
122  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Filtering out modes that aren't %1x%2")
123  .arg(mainresolution.width()).arg(mainresolution.height()));
124 
125  DisplayModeMap screenmap;
126  auto modes = m_device->GetModes();
127  auto physicalsize = m_device->GetPhysicalSize();
128  for (const auto & mode : modes)
129  {
130  auto width = mode->m_width;
131  auto height = mode->m_height;
132  auto rate = mode->m_rate;
133 
134  // Filter out interlaced modes
135  if ((mode->m_flags & DRM_MODE_FLAG_INTERLACE) != 0U)
136  {
137  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Ignoring interlaced mode %1x%2 %3i")
138  .arg(width).arg(height).arg(rate, 2, 'f', 2, '0'));
139  continue;
140  }
141 
142  // Filter out anything that is not the same size as our current screen
143  // i.e. refresh rate changes only
144  if (auto size = QSize(width, height); size != mainresolution)
145  {
146  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Ignoring mode %1x%2 %3")
147  .arg(width).arg(height).arg(rate, 2, 'f', 2, '0'));
148  continue;
149  }
150 
151  QSize resolution(width, height);
152  auto key = MythDisplayMode::CalcKey(resolution, 0.0);
153  if (screenmap.find(key) == screenmap.end())
154  screenmap[key] = MythDisplayMode(resolution, physicalsize, -1.0, rate);
155  else
156  screenmap[key].AddRefreshRate(rate);
157  m_modeMap.insert(MythDisplayMode::CalcKey(resolution, rate), mode->m_index);
158  }
159 
160  for (auto & it : screenmap)
161  m_videoModes.push_back(it.second);
162 
163  DebugModes();
164  return m_videoModes;
165 }
166 
167 bool MythDisplayDRM::SwitchToVideoMode(QSize Size, double DesiredRate)
168 {
169  if (!m_screen || !m_device || !m_device->CanSwitchModes() || m_videoModes.empty())
170  return false;
171 
172  auto rate = static_cast<double>(NAN);
173  QSize dummy(0, 0);
174  MythDisplayMode desired(Size, dummy, -1.0, DesiredRate);
175  int index = MythDisplayMode::FindBestMatch(m_videoModes, desired, rate);
176 
177  if (index < 0)
178  {
179  LOG(VB_GENERAL, LOG_ERR, LOC + "Desired resolution and frame rate not found.");
180  return false;
181  }
182 
183  auto mode = MythDisplayMode::CalcKey(Size, rate);
184  if (!m_modeMap.contains(mode))
185  {
186  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find mode");
187  return false;
188  }
189 
190  return m_device->SwitchMode(m_modeMap.value(mode));
191 }
MythDisplay::m_physicalSize
QSize m_physicalSize
Definition: mythdisplay.h:93
MythDisplayDRM::ScreenChanged
void ScreenChanged(QScreen *qScreen) override
Definition: mythdisplaydrm.cpp:60
MythDisplayDRM::UpdateCurrentMode
void UpdateCurrentMode() override
Retrieve screen details.
Definition: mythdisplaydrm.cpp:95
MythDisplayDRM::GetVideoModes
const MythDisplayModes & GetVideoModes() override
Definition: mythdisplaydrm.cpp:111
MythDisplayDRM::UsingVideoModes
bool UsingVideoModes() override
Definition: mythdisplaydrm.cpp:88
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:423
MythMainWindow::SignalWindowReady
void SignalWindowReady()
MythDisplayDRM::~MythDisplayDRM
~MythDisplayDRM() override
Definition: mythdisplaydrm.cpp:48
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:109
MythDisplay::UpdateCurrentMode
virtual void UpdateCurrentMode()
Retrieve screen details.
Definition: mythdisplay.cpp:473
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:73
MythDisplay::DebugModes
void DebugModes() const
Definition: mythdisplay.cpp:1133
MythDisplayDRM::IsPlanar
bool IsPlanar() override
Definition: mythdisplaydrm.cpp:78
MythDisplayDRM::SwitchToVideoMode
bool SwitchToVideoMode(QSize Size, double DesiredRate) override
Definition: mythdisplaydrm.cpp:167
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:55
MythDisplayDRM::GetDevice
MythDRMPtr GetDevice()
Definition: mythdisplaydrm.cpp:53
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:906
MythDisplay::m_refreshRate
double m_refreshRate
Definition: mythdisplay.h:90
MythDisplay::Initialise
void Initialise()
Definition: mythdisplay.cpp:533
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:104
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