double UIDisplay::GetRefreshRatePriv(void) { CocoaAutoReleasePool pool; double rate = 0.0f; CGDirectDisplayID disp = GetOSXDisplay(m_widget->winId()); if (!disp) { LOG(VB_GENERAL, LOG_WARNING, "Failed to get OS X display"); return rate; } CGDisplayModeRef current = CGDisplayCopyDisplayMode(disp); if (current) { rate = CGDisplayModeGetRefreshRate(current); if (qFuzzyCompare((double)1.0f, rate + 1.0f)) m_variableRefreshRate = true; } else { LOG(VB_GENERAL, LOG_WARNING, "Failed to get current display mode"); return rate; } if (m_variableRefreshRate) { CGDisplayModeRelease(current); return rate; } // if we've run this already, release the modes m_modes.clear(); m_originalModeIndex = -1; if (gDisplayModes) CFRelease(gDisplayModes); gDisplayModes = CGDisplayCopyAllDisplayModes(disp, NULL); if (gDisplayModes) { for (int i = 0; i < CFArrayGetCount(gDisplayModes); ++i) { CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(gDisplayModes, i); int modewidth = CGDisplayModeGetWidth(mode); int modeheight = CGDisplayModeGetHeight(mode); double moderate = CGDisplayModeGetRefreshRate(mode); int32_t flags = CGDisplayModeGetIOFlags(mode); bool interlaced = flags & kDisplayModeInterlacedFlag; CFStringRef fmt = CGDisplayModeCopyPixelEncoding(mode); int depth = DepthFromStringRef(fmt); CFRelease(fmt); bool ignore = modewidth != m_pixelSize.width() || modeheight != m_pixelSize.height() || (flags & kDisplayModeNotGraphicsQualityFlag) || !(flags & kDisplayModeSafetyFlags) || depth < 32 || moderate < 10.0f || moderate > 121.0f; LOG(VB_GUI, LOG_INFO, QString("Mode %1x%2@%3Hz %4bpp%5%6%7") .arg(modewidth).arg(modeheight).arg(moderate).arg(depth) .arg(interlaced ? QString(" Interlaced") : "") .arg(ignore ? QString(" Ignoring") : "") .arg(mode == current ? QString(" CURRENT"): "")); if (!ignore) { m_modes.append(UIDisplayMode(modewidth, modeheight, depth, moderate, interlaced, i)); if (mode == current) m_originalModeIndex = m_modes.size() - 1; } } } CGDisplayModeRelease(current); return rate; }
double UIDisplay::GetRefreshRatePriv(void) { double currentrate = -1; bool currentinterlaced = false; XF86VidModeModeLine mode_line; int dot_clock; // TODO use display when needed const char *displaystring = NULL; Display* display = XOpenDisplay(displaystring); if (!display) { LOG(VB_GENERAL, LOG_ERR, "Failed to open X display."); return currentrate; } int screen = DefaultScreen(display); if (XF86VidModeGetModeLine(display, screen, &dot_clock, &mode_line)) { currentrate = mode_line.htotal * mode_line.vtotal; if (currentrate > 0.0 && dot_clock > 0) { currentrate = (dot_clock * 1000.0) / currentrate; if (((mode_line.flags & V_INTERLACE) != 0) && currentrate > 24.5 && currentrate < 30.5) { currentrate *= 2.0f; currentinterlaced = true; } } else { LOG(VB_GENERAL, LOG_ERR, "Modeline query returned zeroes"); } } else { LOG(VB_GENERAL, LOG_ERR, "Failed to get modeline."); } // all rates m_modes.clear(); m_originalModeIndex = -1; if (UIXRandr.m_valid) { XRRScreenResources *resources = UIXRandr.m_getScreenResources(display, RootWindow(display, screen)); if (resources) { for (int i = 0; i < resources->nmode; ++i) { bool interlaced = false; XRRModeInfo mode = resources->modes[i]; double moderate = mode.hTotal * mode.vTotal; if (moderate > 0.0 && mode.dotClock > 0) { moderate = mode.dotClock / moderate; if ((mode.modeFlags & V_INTERLACE) && moderate > 24.5 && moderate < 30.5) { moderate *= 2.0f; interlaced = true; } } bool ignore = false; bool current = false; bool sizematch = mode.width == (uint)m_pixelSize.width() || mode.height == (uint)m_pixelSize.height(); bool realinterlaced = false; double realrate = UINVControl::GetRateForMode(display, (int)(moderate + 0.5f), realinterlaced); if (realrate > 10.0f && realrate < 121.0f) { ignore = !sizematch; current = sizematch && qFuzzyCompare(realrate + 1.0f, currentrate + 1.0f) && (realinterlaced == interlaced); LOG(VB_GUI, LOG_INFO, QString("nvidia Mode %1: %2x%3@%4%5%6%7") .arg(mode.name).arg(mode.width).arg(mode.height).arg(moderate) .arg(realinterlaced ? QString(" Interlaced") : "") .arg(ignore ? QString(" Ignoring") : "") .arg(current ? QString(" Current") : "")); if (!ignore) m_modes.append(UIDisplayMode(mode.width, mode.height, 32, realrate, realinterlaced, i)); } else { ignore = moderate < 10.0f || moderate > 121.0f || !sizematch; current = sizematch && qFuzzyCompare(moderate + 1.0f, currentrate + 1.0f) && (currentinterlaced == interlaced); LOG(VB_GUI, LOG_INFO, QString("Mode %1: %2x%3@%4%5%6%7") .arg(mode.name).arg(mode.width).arg(mode.height).arg(moderate) .arg(mode.modeFlags & V_INTERLACE ? QString(" Interlaced") : "") .arg(ignore ? QString(" Ignoring") : "") .arg(current ? QString(" Current") : "")); if (!ignore) m_modes.append(UIDisplayMode(mode.width, mode.height, 32, moderate, mode.modeFlags & V_INTERLACE, i)); } if (current) m_originalModeIndex = m_modes.size() - 1; } UIXRandr.m_freeScreenResources(resources); } else { LOG(VB_GENERAL, LOG_INFO, "Need XRandr 1.2 or above to query available refresh rates"); } } XCloseDisplay(display); return currentrate; }