예제 #1
0
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;
}
예제 #2
0
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;
}