Exemplo n.º 1
0
void ShowProgressDialog(QWidget *window, const QString &labelText, ProgressFinishedMethod finished,
                        ProgressUpdateMethod update)
{
  RDProgressDialog dialog(labelText, window);

  // if we don't have an update function, set the progress display to be 'infinite spinner'
  dialog.setInfinite(!update);

  QSemaphore tickerSemaphore(1);

  // start a lambda thread to tick our functions and close the progress dialog when we're done.
  LambdaThread progressTickerThread([finished, update, &dialog, &tickerSemaphore]() {
    while(tickerSemaphore.available())
    {
      QThread::msleep(30);

      if(update)
        GUIInvoke::call([update, &dialog]() { dialog.setPercentage(update()); });

      GUIInvoke::call([finished, &tickerSemaphore]() {
        if(finished())
          tickerSemaphore.tryAcquire();
      });
    }

    GUIInvoke::call([&dialog]() { dialog.closeAndReset(); });
  });
  progressTickerThread.start();

  // show the dialog
  RDDialog::show(&dialog);

  // signal the thread to exit if somehow we got here without it finishing, then wait for it thread
  // to clean itself up
  tickerSemaphore.tryAcquire();
  progressTickerThread.wait();
}
Exemplo n.º 2
0
void CaptureContext::LoadLogfileThreaded(const QString &logFile, const QString &origFilename,
                                         bool temporary, bool local)
{
  QFileInfo fi(ConfigFile("UI.config"));

  m_LogFile = origFilename;

  m_LogLocal = local;

  m_LoadInProgress = true;

  if(fi.exists())
    Config.Serialize(fi.absoluteFilePath());

  float loadProgress = 0.0f;
  float postloadProgress = 0.0f;

  QSemaphore progressThread(1);

  LambdaThread progressTickerThread([this, &progressThread, &loadProgress, &postloadProgress]() {
    while(progressThread.available())
    {
      QThread::msleep(30);

      float val = 0.8f * loadProgress + 0.19f * postloadProgress + 0.01f;

      GUIInvoke::call([this, val]() {
        m_Progress->setValue(val * 1000);
        m_MainWindow->setProgress(val);
      });
    }
    GUIInvoke::call([this]() { m_Progress->setValue(1000); });
  });
  progressTickerThread.start();

  // this function call will block until the log is either loaded, or there's some failure
  m_Renderer.OpenCapture(logFile, &loadProgress);

  // if the renderer isn't running, we hit a failure case so display an error message
  if(!m_Renderer.IsRunning())
  {
    QString errmsg = "Unknown error message";
    errmsg = ToQStr(m_Renderer.GetCreateStatus());

    progressThread.acquire();
    progressTickerThread.wait();

    RDDialog::critical(NULL, "Error opening log",
                       QString("%1\nFailed to open logfile for replay: %2.\n\n"
                               "Check diagnostic log in Help menu for more details.")
                           .arg(logFile)
                           .arg(errmsg));

    GUIInvoke::call([this]() {
      m_Progress->setValue(1000);
      m_MainWindow->setProgress(-1.0f);
      m_Progress->hide();
    });

    m_LoadInProgress = false;

    return;
  }

  if(!temporary)
  {
    PersistantConfig::AddRecentFile(Config.RecentLogFiles, origFilename, 10);

    if(fi.exists())
      Config.Serialize(fi.absoluteFilePath());
  }

  m_EventID = 0;

  // fetch initial data like drawcalls, textures and buffers
  m_Renderer.BlockInvoke([this, &postloadProgress](IReplayRenderer *r) {
    r->GetFrameInfo(&m_FrameInfo);

    m_APIProps = r->GetAPIProperties();

    postloadProgress = 0.2f;

    r->GetDrawcalls(&m_Drawcalls);

    postloadProgress = 0.4f;

    r->GetSupportedWindowSystems(&m_WinSystems);

#if defined(RENDERDOC_PLATFORM_WIN32)
    m_CurWinSystem = eWindowingSystem_Win32;
#elif defined(RENDERDOC_PLATFORM_LINUX)
    m_CurWinSystem = eWindowingSystem_Xlib;

    // prefer XCB, if supported
    for(WindowingSystem sys : m_WinSystems)
    {
      if(sys == eWindowingSystem_XCB)
      {
        m_CurWinSystem = eWindowingSystem_XCB;
        break;
      }
    }

    if(m_CurWinSystem == eWindowingSystem_XCB)
      m_XCBConnection = QX11Info::connection();
    else
      m_X11Display = QX11Info::display();
#endif

    r->GetBuffers(&m_BufferList);
    for(FetchBuffer &b : m_BufferList)
      m_Buffers[b.ID] = &b;

    postloadProgress = 0.8f;

    r->GetTextures(&m_TextureList);
    for(FetchTexture &t : m_TextureList)
      m_Textures[t.ID] = &t;

    postloadProgress = 0.9f;

    r->GetD3D11PipelineState(&CurD3D11PipelineState);
    r->GetD3D12PipelineState(&CurD3D12PipelineState);
    r->GetGLPipelineState(&CurGLPipelineState);
    r->GetVulkanPipelineState(&CurVulkanPipelineState);
    CurPipelineState.SetStates(m_APIProps, &CurD3D11PipelineState, &CurD3D12PipelineState,
                               &CurGLPipelineState, &CurVulkanPipelineState);

    UnreadMessageCount = 0;
    AddMessages(m_FrameInfo.debugMessages);

    postloadProgress = 1.0f;
  });

  QThread::msleep(20);

  QDateTime today = QDateTime::currentDateTimeUtc();
  QDateTime compare = today.addDays(-21);

  if(compare > Config.DegradedLog_LastUpdate && m_APIProps.degraded)
  {
    Config.DegradedLog_LastUpdate = today;

    RDDialog::critical(
        NULL, "Degraded support of log",
        QString(
            "%1\nThis log opened with degraded support - "
            "this could mean missing hardware support caused a fallback to software rendering.\n\n"
            "This warning will not appear every time this happens, "
            "check debug errors/warnings window for more details.")
            .arg(origFilename));
  }

  m_LogLoaded = true;

  progressThread.acquire();
  progressTickerThread.wait();

  QVector<ILogViewerForm *> logviewers(m_LogViewers);

  GUIInvoke::blockcall([&logviewers]() {
    // notify all the registers log viewers that a log has been loaded
    for(ILogViewerForm *logviewer : logviewers)
    {
      if(logviewer)
        logviewer->OnLogfileLoaded();
    }
  });

  m_LoadInProgress = false;

  GUIInvoke::call([this]() {
    m_Progress->setValue(1000);
    m_MainWindow->setProgress(1.0f);
    m_Progress->hide();
  });
}