MythTV  master
mythdisplayosx.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "config.h"
3 #include "mythcorecontext.h"
4 #include "mythmainwindow.h"
5 #include "mythdisplayosx.h"
6 #import "mythosxutils.h"
7 #import "mythutilscocoa.h"
8 
9 #define LOC QString("DisplayOSX: ")
10 
12  : MythDisplay()
13 {
14  Initialise();
15 }
16 
18 {
19  ClearModes();
20 }
21 
23 {
24  QWidget* widget = m_widget;
25 
26  if (!widget)
27  {
28  if (!HasMythMainWindow())
29  {
31  return;
32  }
33  widget = qobject_cast<QWidget*>(MythMainWindow::getMainWindow());
34  }
35 
36  CGDirectDisplayID disp = GetOSXDisplay(widget->winId());
37  if (!disp)
38  {
40  return;
41  }
42  CGDisplayModeRef mode = CGDisplayCopyDisplayMode(disp);
43  if (!mode)
44  {
46  return;
47  }
48 
49  m_modeComplete = true;
50  m_refreshRate = CGDisplayModeGetRefreshRate(mode);
51  m_resolution = QSize(static_cast<int>(CGDisplayModeGetWidth(mode)),
52  static_cast<int>(CGDisplayModeGetHeight(mode)));
53  QByteArray edid = GetOSXEDID(disp);
54  m_edid = MythEDID(edid);
55  //bool interlaced = CGDisplayModeGetIOFlags(mode) & kDisplayModeInterlacedFlag;
56  CGDisplayModeRelease(mode);
57  CGSize sizemm = CGDisplayScreenSize(disp);
58  m_physicalSize = QSize(static_cast<int>(sizemm.width), static_cast<int>(sizemm.height));
59 }
60 
62 {
63  if (gCoreContext)
64  return gCoreContext->GetBoolSetting("UseVideoModes", false);
65  return false;
66 }
67 
68 const std::vector<MythDisplayMode>& MythDisplayOSX::GetVideoModes(void)
69 {
70  if (!m_videoModes.empty() || !HasMythMainWindow())
71  return m_videoModes;
72 
73  ClearModes();
74 
75  WId win = (qobject_cast<QWidget*>(MythMainWindow::getMainWindow()))->winId();
76  CGDirectDisplayID disp = GetOSXDisplay(win);
77  if (!disp)
78  return m_videoModes;
79  CFArrayRef modes = CGDisplayCopyAllDisplayModes(disp, nullptr);
80  if (!modes)
81  return m_videoModes;
82 
83  DisplayModeMap screen_map;
84  CGSize sizemm = CGDisplayScreenSize(disp);
85 
86  for (int i = 0; i < CFArrayGetCount(modes); ++i)
87  {
88  CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);
89  double rate = CGDisplayModeGetRefreshRate(mode);
90  bool interlaced = CGDisplayModeGetIOFlags(mode) & kDisplayModeInterlacedFlag;
91  int width = static_cast<int>(CGDisplayModeGetWidth(mode));
92  int height = static_cast<int>(CGDisplayModeGetHeight(mode));
93 
94  // See note in MythDisplayX11
95  if (interlaced)
96  {
97  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Ignoring interlaced mode %1x%2 %3i")
98  .arg(width).arg(height).arg(rate, 2, 'f', 2, '0'));
99  continue;
100  }
101 
102  QSize resolution(width, height);
103  uint64_t key = MythDisplayMode::CalcKey(resolution, 0.0);
104  if (screen_map.find(key) == screen_map.end())
105  screen_map[key] = MythDisplayMode(resolution, QSize(sizemm.width, sizemm.height),
106  -1.0, rate);
107  else
108  screen_map[key].AddRefreshRate(rate);
109  m_modeMap.insert(MythDisplayMode::CalcKey(resolution, rate), CGDisplayModeRetain(mode));
110  }
111 
112  CFRelease(modes);
113 
114  for (auto it = screen_map.begin(); screen_map.end() != it; ++it)
115  m_videoModes.push_back(it->second);
116  DebugModes();
117  return m_videoModes;
118 }
119 
120 bool MythDisplayOSX::SwitchToVideoMode(QSize Size, double DesiredRate)
121 {
122  if (!HasMythMainWindow())
123  return false;
124  WId win = (qobject_cast<QWidget*>(MythMainWindow::getMainWindow()))->winId();
125  CGDirectDisplayID disp = GetOSXDisplay(win);
126  if (!disp)
127  return false;
128 
129  auto rate = static_cast<double>(NAN);
130  MythDisplayMode desired(Size, QSize(0, 0), -1.0, DesiredRate);
131  int idx = MythDisplayMode::FindBestMatch(m_videoModes, desired, rate);
132  if (idx < 0)
133  {
134  LOG(VB_GENERAL, LOG_ERR, LOC + "Desired resolution and frame rate not found.");
135  return false;
136  }
137 
138  auto mode = MythDisplayMode::CalcKey(Size, rate);
139  if (!m_modeMap.contains(mode))
140  {
141  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find mode");
142  return false;
143  }
144 
145  // switch mode and return success
146  CGDisplayCapture(disp);
147  CGDisplayConfigRef cfg;
148  CGBeginDisplayConfiguration(&cfg);
149  CGConfigureDisplayFadeEffect(cfg, 0.3f, 0.5f, 0, 0, 0);
150  CGDisplaySetDisplayMode(disp, m_modeMap.value(mode), nullptr);
151  CGError err = CGCompleteDisplayConfiguration(cfg, kCGConfigureForAppOnly);
152  CGDisplayRelease(disp);
153  return err == kCGErrorSuccess;
154 }
155 
157 {
158  for (auto it = m_modeMap.cbegin(); it != m_modeMap.cend(); ++it)
159  CGDisplayModeRelease(it.value());
160  m_modeMap.clear();
161  m_videoModes.clear();
162 }
MythDisplay::m_physicalSize
QSize m_physicalSize
Definition: mythdisplay.h:86
MythDisplay::m_resolution
QSize m_resolution
Definition: mythdisplay.h:85
MythDisplayMode::CalcKey
static uint64_t CalcKey(QSize Size, double Rate)
Definition: mythdisplaymode.cpp:126
MythDisplayOSX::~MythDisplayOSX
~MythDisplayOSX() override
Definition: mythdisplayosx.cpp:17
arg
arg(title).arg(filename).arg(doDelete))
MythDisplayOSX::MythDisplayOSX
MythDisplayOSX()
Definition: mythdisplayosx.cpp:11
MythDisplayOSX::ClearModes
void ClearModes(void)
Definition: mythdisplayosx.cpp:156
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
mythosxutils.h
HasMythMainWindow
bool HasMythMainWindow(void)
Definition: mythmainwindow.cpp:113
MythDisplay::UpdateCurrentMode
virtual void UpdateCurrentMode()
Retrieve screen details.
Definition: mythdisplay.cpp:425
MythDisplay::m_modeComplete
bool m_modeComplete
Definition: mythdisplay.h:82
mythdisplayosx.h
MythMainWindow::getMainWindow
static MythMainWindow * getMainWindow(bool useDB=true)
Return the existing main window, or create one.
Definition: mythmainwindow.cpp:84
MythDisplay::DebugModes
void DebugModes() const
Definition: mythdisplay.cpp:1019
MythDisplay::m_edid
MythEDID m_edid
Definition: mythdisplay.h:87
MythDisplayMode::FindBestMatch
static int FindBestMatch(const std::vector< MythDisplayMode > &Modes, const MythDisplayMode &Mode, double &TargetRate)
Definition: mythdisplaymode.cpp:139
MythDisplay::m_videoModes
std::vector< MythDisplayMode > m_videoModes
Definition: mythdisplay.h:91
f
QTextStream t & f
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:603
GetOSXEDID
QByteArray GetOSXEDID(CGDirectDisplayID Display)
Definition: mythutilscocoa.mm:30
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
MythDisplayOSX::UpdateCurrentMode
void UpdateCurrentMode(void) override
Retrieve screen details.
Definition: mythdisplayosx.cpp:22
MythDisplay
Definition: mythdisplay.h:19
MythDisplayMode
Definition: mythdisplaymode.h:21
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:927
LOC
#define LOC
Definition: mythdisplayosx.cpp:9
MythDisplay::m_refreshRate
double m_refreshRate
Definition: mythdisplay.h:83
MythDisplay::Initialise
void Initialise()
Definition: mythdisplay.cpp:487
MythDisplay::m_widget
QWidget * m_widget
Definition: mythdisplay.h:88
mythcorecontext.h
DisplayModeMap
std::map< uint64_t, MythDisplayMode > DisplayModeMap
Definition: mythdisplaymode.h:18
MythDisplayOSX::GetVideoModes
const std::vector< MythDisplayMode > & GetVideoModes(void) override
Definition: mythdisplayosx.cpp:68
MythDisplayOSX::m_modeMap
QMap< uint64_t, CGDisplayModeRef > m_modeMap
Definition: mythdisplayosx.h:25
MythDisplayOSX::UsingVideoModes
bool UsingVideoModes(void) override
Definition: mythdisplayosx.cpp:61
MythDisplayOSX::SwitchToVideoMode
bool SwitchToVideoMode(QSize Size, double DesiredRate) override
Definition: mythdisplayosx.cpp:120
GetOSXDisplay
CGDirectDisplayID GetOSXDisplay(WId win)
Definition: mythosxutils.cpp:70
mythmainwindow.h
mythutilscocoa.h
MythEDID
Definition: mythedid.h:18