MythTV  master
DisplayRes.cpp
Go to the documentation of this file.
1 
2 #include "DisplayRes.h"
3 #include "config.h"
4 #include "mythlogging.h"
5 #include "mythdb.h"
6 
7 #ifdef USING_XRANDR
8 #include "DisplayResX.h"
9 #endif
10 #if CONFIG_DARWIN
11 #include "DisplayResOSX.h"
12 #endif
13 
14 
16 bool DisplayRes::s_locked = false;
17 
19 {
20  if (lock && s_locked)
21  return nullptr;
22 
23  if (!s_instance)
24  {
25 #ifdef USING_XRANDR
26  s_instance = new DisplayResX();
27 #elif CONFIG_DARWIN
28  s_instance = new DisplayResOSX();
29 #endif
30  }
31 
32  if (s_instance && lock)
33  s_locked = true;
34 
35  return s_instance;
36 }
37 
39 {
40  s_locked = false;
41 }
42 
44 {
45  if (s_instance)
47 }
48 
50 {
51  int tW = 0, tH = 0, tW_mm = 0, tH_mm = 0;
52  double tAspect = 0.0;
53  double tRate = 0.0;
54 
55  m_last.Init();
56  m_curMode = GUI;
57  m_pixelAspectRatio = 1.0;
58 
59  // Initialise DESKTOP mode
60  GetDisplayInfo(tW, tH, tW_mm, tH_mm, tRate, m_pixelAspectRatio);
61  m_mode[DESKTOP].Init();
62  m_mode[DESKTOP] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, tRate);
63  LOG(VB_GENERAL, LOG_NOTICE, QString("Desktop video mode: %1x%2 %3 Hz")
64  .arg(tW).arg(tH).arg(tRate, 0, 'f', 3));
65 
66  // Initialize GUI mode
67  m_mode[GUI].Init();
68  tW = tH = 0;
69  GetMythDB()->GetResolutionSetting("GuiVidMode", tW, tH, tAspect, tRate);
70  GetMythDB()->GetResolutionSetting("DisplaySize", tW_mm, tH_mm);
71  m_mode[GUI] = DisplayResScreen(tW, tH, tW_mm, tH_mm, -1.0, tRate);
72 
73  if (m_mode[DESKTOP] == m_mode[GUI] && tRate == 0)
74  {
75  // same resolution as current desktop
77  }
78 
79  // Initialize default VIDEO mode
80  tW = tH = 0;
81  GetMythDB()->GetResolutionSetting("TVVidMode", tW, tH, tAspect, tRate);
82  m_mode[VIDEO] = DisplayResScreen(tW, tH, tW_mm, tH_mm, tAspect, tRate);
83 
84 
85  // Initialize video override mode
86  m_inSizeToOutputMode.clear();
87 
88  for (int i = 0; true; ++i)
89  {
90  int iw = 0, ih = 0, ow = 0, oh = 0;
91  double iaspect = 0.0, oaspect = 0.0;
92  double irate = 0.0, orate = 0.0;
93 
94  GetMythDB()->GetResolutionSetting("VidMode", iw, ih, iaspect, irate, i);
95  GetMythDB()->GetResolutionSetting("TVVidMode", ow, oh, oaspect, orate, i);
96 
97  if (!(iw || ih || irate))
98  break;
99 
100  if (!(ih && ow && oh))
101  break;
102 
103  uint64_t key = DisplayResScreen::CalcKey(iw, ih, irate);
104 
105  DisplayResScreen scr(ow, oh, tW_mm, tH_mm, oaspect, orate);
106 
107  m_inSizeToOutputMode[key] = scr;
108  }
109 
110  // Find maximum resolution, needed for initializing X11 window
111  const DisplayResVector& screens = GetVideoModes();
112 
113  for (size_t i = 0; i < screens.size(); ++i)
114  {
115  m_maxWidth = std::max(m_maxWidth, screens[i].Width());
116  m_maxHeight = std::max(m_maxHeight, screens[i].Height());
117  }
118 
119  LOG(VB_PLAYBACK, LOG_INFO, QString("max_width: %1 max_height: %2")
120 
121  .arg(m_maxWidth).arg(m_maxHeight));
122 
123  return true;
124 }
125 
126 bool DisplayRes::SwitchToVideo(int iwidth, int iheight, double frate)
127 {
128  tmode next_mode = VIDEO; // default VIDEO mode
129  DisplayResScreen next = m_mode[next_mode];
130  double target_rate = 0.0;
131 
132  // try to find video override mode
134  iwidth, iheight, frate);
135 
136  if (key != 0)
137  {
138  m_mode[next_mode = CUSTOM_VIDEO] = next = m_inSizeToOutputMode[key];
139  LOG(VB_PLAYBACK, LOG_INFO, QString("Found custom screen override %1x%2")
140  .arg(next.Width()).arg(next.Height()));
141  }
142 
143  // If requested refresh rate is 0, attempt to match video fps
144  if ((int) next.RefreshRate() == 0)
145  {
146  LOG(VB_PLAYBACK, LOG_INFO,
147  QString("Trying to match best refresh rate %1Hz")
148  .arg(frate, 0, 'f', 3));
149  next.SetRefreshRate(frate);
150  }
151 
152  // need to change video mode?
154 
155  bool chg = !(next == m_last) ||
157  target_rate));
158 
159  LOG(VB_GENERAL, LOG_INFO, QString("%1 %2x%3 %4 Hz")
160  .arg(chg ? "Changing to" : "Using")
161  .arg(next.Width()).arg(next.Height())
162  .arg(target_rate, 0, 'f', 3));
163 
164  if (chg && !SwitchToVideoMode(next.Width(), next.Height(), target_rate))
165  {
166  LOG(VB_GENERAL, LOG_ERR, QString("SwitchToVideo: Video size %1 x %2: "
167  "xrandr failed for %3 x %4")
168  .arg(iwidth).arg(iheight)
169  .arg(next.Width()).arg(next.Height()));
170  return false;
171  }
172 
173  m_curMode = next_mode;
174 
175  m_last = next;
176  m_last.SetRefreshRate(target_rate);
177 
178  LOG(VB_PLAYBACK, LOG_INFO,
179  QString("SwitchToVideo: Video size %1 x %2: \n"
180  " %7 displaying resolution %3 x %4, %5mm x %6mm")
181  .arg(iwidth).arg(iheight).arg(GetWidth()).arg(GetHeight())
182  .arg(GetPhysicalWidth()).arg(GetPhysicalHeight())
183  .arg((chg) ? "Switched to" : "Already"));
184 
185  return chg;
186 }
187 
189 {
190  DisplayResScreen next = m_mode[next_mode];
191  double target_rate;
192 
193  // need to change video mode?
194  // If GuiVidModeRefreshRate is 0, assume any refresh rate is good enough.
195  if (next.RefreshRate() == 0)
196  {
197  next.SetRefreshRate(m_last.RefreshRate());
198  }
199 
201  bool chg = !(next == m_last) ||
203  target_rate));
204 
205  LOG(VB_GENERAL, LOG_INFO, QString("%1 %2x%3 %4 Hz")
206  .arg(chg ? "Changing to" : "Using")
207  .arg(next.Width()).arg(next.Height())
208  .arg(target_rate, 0, 'f', 3));
209 
210  if (chg && !SwitchToVideoMode(next.Width(), next.Height(), target_rate))
211  {
212  LOG(VB_GENERAL, LOG_ERR,
213  QString("SwitchToGUI: xrandr failed for %1x%2 %3 Hz")
214  .arg(next.Width()).arg(next.Height())
215  .arg(next.RefreshRate(), 0, 'f', 3));
216  return false;
217  }
218 
219  m_curMode = next_mode;
220 
221  m_last = next;
222  m_last.SetRefreshRate(target_rate);
223 
224  LOG(VB_GENERAL, LOG_INFO, QString("SwitchToGUI: Switched to %1x%2 %3 Hz")
225  .arg(GetWidth()).arg(GetHeight()).arg(GetRefreshRate(), 0, 'f', 3));
226 
227  return chg;
228 }
229 
230 bool DisplayRes::SwitchToCustomGUI(int width, int height, short rate)
231 {
232  m_mode[CUSTOM_GUI] = DisplayResScreen(width, height, m_mode[GUI].Width_mm(),
233  m_mode[GUI].Height_mm(), -1.0,
234  (double)rate);
235  return SwitchToGUI(CUSTOM_GUI);
236 }
237 
238 std::vector<double> DisplayRes::GetRefreshRates(int width,
239  int height) const
240 {
241  double tr;
242  std::vector<double> empty;
243 
244  const DisplayResScreen drs(width, height, 0, 0, -1.0, 0.0);
245  const DisplayResVector& drv = GetVideoModes();
246  int t = DisplayResScreen::FindBestMatch(drv, drs, tr);
247 
248  if (t < 0)
249  return empty;
250 
251  return drv[t].RefreshRates();
252 }
253 
263 {
264  DisplayRes *display_res = DisplayRes::GetDisplayRes();
265 
266  if (display_res)
267  return display_res->GetVideoModes();
268 
269  DisplayResVector empty;
270 
271  return empty;
272 }
static DisplayRes * GetDisplayRes(bool lock=false)
Factory method that returns a DisplayRes singleton.
Definition: DisplayRes.cpp:18
tmode m_curMode
Definition: DisplayRes.h:152
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
DisplayResScreen m_mode[MAX_MODES]
Definition: DisplayRes.h:153
DisplayResMap m_inSizeToOutputMode
maps input video parameters to output video modes
Definition: DisplayRes.h:157
static void Unlock(void)
Release any access restrictions.
Definition: DisplayRes.cpp:38
bool SwitchToCustomGUI(int width, int height, short rate=0)
Switches to the custom GUI resolution specified.
Definition: DisplayRes.cpp:230
virtual bool GetDisplayInfo(int &w_pix, int &h_pix, int &w_mm, int &h_mm, double &rate, double &par) const =0
static bool s_locked
Definition: DisplayRes.h:164
Definition: DisplayRes.h:24
virtual const DisplayResVector & GetVideoModes() const =0
Returns all video modes supported by the display.
virtual bool SwitchToVideoMode(int width, int height, double framerate)=0
double m_pixelAspectRatio
Definition: DisplayRes.h:161
int GetWidth(void) const
Returns current screen width in pixels.
Definition: DisplayRes.h:101
unsigned char t
Definition: ParseText.cpp:329
double RefreshRate() const
int GetHeight(void) const
Returns current screen width in pixels.
Definition: DisplayRes.h:104
std::vector< DisplayResScreen > DisplayResVector
bool Initialize(void)
Initialize DisplayRes, normally called automatically.
Definition: DisplayRes.cpp:49
int GetPhysicalHeight(void) const
Returns current screen height in millimeters.
Definition: DisplayRes.h:110
int GetPhysicalWidth(void) const
Returns current screen width in millimeters.
Definition: DisplayRes.h:107
int m_maxWidth
Definition: DisplayRes.h:159
double GetRefreshRate(void) const
Returns current screen refresh rate.
Definition: DisplayRes.h:113
void SetRefreshRate(double rr)
PictureAttribute next(PictureAttributeSupported supported, PictureAttribute attribute)
static uint64_t CalcKey(int w, int h, double rate)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
bool SwitchToGUI(tmode next_mode=GUI)
Switches to the GUI resolution specified.
Definition: DisplayRes.cpp:188
tmode
Definition: DisplayRes.h:22
static int FindBestMatch(const DisplayResVector &dsr, const DisplayResScreen &d, double &target_rate)
int m_maxHeight
Definition: DisplayRes.h:159
static DisplayRes * s_instance
Definition: DisplayRes.h:163
DisplayResScreen m_last
Definition: DisplayRes.h:154
MythDB * GetMythDB(void)
Definition: mythdb.cpp:46
The DisplayRes module allows for the display resolution and refresh rateto be changed "on the fly".
Definition: DisplayRes.h:32
GetVideoModes(void)
Returns all video modes available.
Definition: DisplayRes.cpp:262
bool SwitchToVideo(int iwidth, int iheight, double frate=0.0)
Switches to the resolution and refresh rate defined in the database for the specified video resolutio...
Definition: DisplayRes.cpp:126
std::vector< double > GetRefreshRates(int width, int height) const
Returns refresh rates available at a specific screen resolution.
Definition: DisplayRes.cpp:238
static bool compare_rates(double f1, double f2, double precision=0.01)
static uint64_t FindBestScreen(const DisplayResMap &resmap, int iwidth, int iheight, double frate)
static void SwitchToDesktop(void)
Return the screen to the original desktop settings.
Definition: DisplayRes.cpp:43