Exemplo n.º 1
0
void CWinSystemX11GL::SetVSyncImpl(bool enable)
{
  /* turn of current setting first */
  if(m_glXSwapIntervalSGI)
    m_glXSwapIntervalSGI(0);
  if(m_glXSwapIntervalMESA)
    m_glXSwapIntervalMESA(0);

  m_iVSyncErrors = 0;

  CStdString strVendor(m_RenderVendor);
  strVendor.ToLower();

  if(!enable)
    return;

  bool vendor_nvidia = strVendor.find("nvidia") != std::string::npos;
  bool vendor_ati    = strVendor.compare(0, 3, "ati") == 0;

  if (m_glXSwapIntervalMESA && !m_iVSyncMode && vendor_ati)
  {
    if(m_glXSwapIntervalMESA(1) == 0)
      m_iVSyncMode = 2;
    else
      CLog::Log(LOGWARNING, "%s - glXSwapIntervalMESA failed", __FUNCTION__);
  }

  if(m_glXGetSyncValuesOML && m_glXSwapBuffersMscOML && !m_iVSyncMode)
  {
    int64_t ust, msc, sbc;
    if(m_glXGetSyncValuesOML(m_dpy, m_glWindow, &ust, &msc, &sbc))
      m_iVSyncMode = 5;
    else
      CLog::Log(LOGWARNING, "%s - glXGetSyncValuesOML failed", __FUNCTION__);
  }
  if (m_glXWaitVideoSyncSGI && m_glXGetVideoSyncSGI && !m_iVSyncMode && !vendor_nvidia)
  {
    unsigned int count;
    if(m_glXGetVideoSyncSGI(&count) == 0)
        m_iVSyncMode = 3;
    else
      CLog::Log(LOGWARNING, "%s - glXGetVideoSyncSGI failed, glcontext probably not direct", __FUNCTION__);
  }
  if (m_glXSwapIntervalSGI && !m_iVSyncMode)
  {
    if(m_glXSwapIntervalSGI(1) == 0)
      m_iVSyncMode = 2;
    else
      CLog::Log(LOGWARNING, "%s - glXSwapIntervalSGI failed", __FUNCTION__);
  }
  if (m_glXSwapIntervalMESA && !m_iVSyncMode && !vendor_ati)
  {
    if(m_glXSwapIntervalMESA(1) == 0)
      m_iVSyncMode = 2;
    else
      CLog::Log(LOGWARNING, "%s - glXSwapIntervalMESA failed", __FUNCTION__);
  }

}
Exemplo n.º 2
0
bool CWinSystemX11GL::PresentRenderImpl(const CDirtyRegionList& dirty)
{
  CheckDisplayEvents();

  if(m_iVSyncMode == 3)
  {
    glFinish();
    unsigned int before = 0, after = 0;
    if(m_glXGetVideoSyncSGI(&before) != 0)
      CLog::Log(LOGERROR, "%s - glXGetVideoSyncSGI - Failed to get current retrace count", __FUNCTION__);

    glXSwapBuffers(m_dpy, m_glWindow);
    glFinish();

    if(m_glXGetVideoSyncSGI(&after) != 0)
      CLog::Log(LOGERROR, "%s - glXGetVideoSyncSGI - Failed to get current retrace count", __FUNCTION__);

    if(after == before)
      m_iVSyncErrors = 1;
    else
      m_iVSyncErrors--;

    if(m_iVSyncErrors > 0)
    {
      CLog::Log(LOGINFO, "GL: retrace count didn't change after buffer swap, switching to vsync mode 4");
      m_iVSyncErrors = 0;
      m_iVSyncMode   = 4;
    }

    if(m_iVSyncErrors < -200)
    {
      CLog::Log(LOGINFO, "GL: retrace count change for %d consecutive buffer swap, switching to vsync mode 2", -m_iVSyncErrors);
      m_iVSyncErrors = 0;
      m_iVSyncMode   = 2;
    }
  }
  else if (m_iVSyncMode == 4)
  {
    glFinish();
    unsigned int before = 0, swap = 0, after = 0;
    if(m_glXGetVideoSyncSGI(&before) != 0)
      CLog::Log(LOGERROR, "%s - glXGetVideoSyncSGI - Failed to get current retrace count", __FUNCTION__);

    if(m_glXWaitVideoSyncSGI(2, (before+1)%2, &swap) != 0)
      CLog::Log(LOGERROR, "%s - glXWaitVideoSyncSGI - Returned error", __FUNCTION__);

    glXSwapBuffers(m_dpy, m_glWindow);
    glFinish();

    if(m_glXGetVideoSyncSGI(&after) != 0)
      CLog::Log(LOGERROR, "%s - glXGetVideoSyncSGI - Failed to get current retrace count", __FUNCTION__);

    if(after == before)
      CLog::Log(LOGERROR, "%s - glXWaitVideoSyncSGI - Woke up early", __FUNCTION__);

    if(after > before + 1)
      m_iVSyncErrors++;
    else
      m_iVSyncErrors = 0;

    if(m_iVSyncErrors > 30)
    {
      CLog::Log(LOGINFO, "GL: retrace count seems to be changing due to the swapbuffers call, switching to vsync mode 3");
      m_iVSyncMode   = 3;
      m_iVSyncErrors = 0;
    }
  }
  else if (m_iVSyncMode == 5)
  {
    int64_t ust, msc, sbc;
    if(m_glXGetSyncValuesOML(m_dpy, m_glWindow, &ust, &msc, &sbc))
      m_glXSwapBuffersMscOML(m_dpy, m_glWindow, msc, 0, 0);
    else
      CLog::Log(LOGERROR, "%s - glXSwapBuffersMscOML - Failed to get current retrace count", __FUNCTION__);
  }
  else
    glXSwapBuffers(m_dpy, m_glWindow);

  return true;
}