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 #ifdef USING_QTPRIVATEHEADERS
13  if (m_device)
14  m_device->MainWindowReady();
15 #endif
16 }
17 
19 {
20 #ifdef USING_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 
39 MythDisplayDRM::MythDisplayDRM([[maybe_unused]] MythMainWindow* MainWindow)
40 {
42  Initialise();
43 #ifdef USING_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)
61 void 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 #ifdef USING_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
101  GetVideoModes();
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 
168 bool 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 }
MythDisplay::m_physicalSize
QSize m_physicalSize
Definition: mythdisplay.h:93
MythDisplayDRM::ScreenChanged
void ScreenChanged(QScreen *qScreen) override
Definition: mythdisplaydrm.cpp:61
MythDisplayDRM::UpdateCurrentMode
void UpdateCurrentMode() override
Retrieve screen details.
Definition: mythdisplaydrm.cpp:96
MythDisplayDRM::GetVideoModes
const MythDisplayModes & GetVideoModes() override
Definition: mythdisplaydrm.cpp:112
MythDisplayDRM::UsingVideoModes
bool UsingVideoModes() override
Definition: mythdisplaydrm.cpp:89
MythDisplayDRM::MainWindowReady
void MainWindowReady()
Definition: mythdisplaydrm.cpp:10
LOC
#define LOC
Definition: mythdisplaydrm.cpp:8
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:49
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:317
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:39
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:74
MythDisplay::DebugModes
void DebugModes() const
Definition: mythdisplay.cpp:1133
MythDisplayDRM::IsPlanar
bool IsPlanar() override
Definition: mythdisplaydrm.cpp:79
MythDisplayDRM::SwitchToVideoMode
bool SwitchToVideoMode(QSize Size, double DesiredRate) override
Definition: mythdisplaydrm.cpp:168
mythlogging.h
mythdisplaydrm.h
MythDRMPtr
std::shared_ptr< class MythDRMDevice > MythDRMPtr
Definition: mythdrmdevice.h:17
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:57
MythDisplayDRM::GetDevice
MythDRMPtr GetDevice()
Definition: mythdisplaydrm.cpp:54
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:912
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:18
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