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