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