diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.cpp b/qrenderdoc/Windows/Dialogs/LiveCapture.cpp index f52981f5e..fa383d4a3 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.cpp +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "LiveCapture.h" +#include #include #include #include @@ -112,10 +113,20 @@ LiveCapture::LiveCapture(ICaptureContext &ctx, const QString &hostname, const QS ui->preview->setMouseTracking(true); - setTitle(tr("Connecting..")); - ui->connectionStatus->setText(tr("Connecting..")); + setTitle(tr("Connecting")); + ui->connectionStatus->setText(tr("Connecting")); ui->connectionIcon->setPixmap(Pixmaps::hourglass(ui->connectionIcon)); + ui->apiIcon->setVisible(false); + + ui->triggerCapture->setEnabled(false); + ui->queueCap->setEnabled(false); + + ui->target->setText(QString()); + + ui->captureProgressLabel->setVisible(false); + ui->captureProgress->setVisible(false); + ui->captures->setItemDelegate(new NameEditOnlyDelegate(this)); { @@ -566,6 +577,41 @@ bool LiveCapture::checkAllowDelete() return (res == QMessageBox::Yes); } +void LiveCapture::updateAPIStatus() +{ + QString apiStatus; + + bool nonpresenting = false; + + // add any fully working APIs first in the list. + for(QString api : m_APIs.keys()) + { + if(m_APIs[api].supported && m_APIs[api].presenting) + apiStatus += lit(", %1").arg(api); + } + + // then add any problem APIs + for(QString api : m_APIs.keys()) + { + if(!m_APIs[api].supported) + { + apiStatus += tr(", %1 (Unsupported)").arg(api); + } + else if(!m_APIs[api].presenting) + { + apiStatus += tr(", %1 (Not Presenting)").arg(api); + nonpresenting = true; + } + } + + // remove the redundant starting ", " + apiStatus.remove(0, 2); + + ui->apiStatus->setText(apiStatus); + + ui->apiIcon->setVisible(nonpresenting); +} + QString LiveCapture::MakeText(Capture *cap) { QString text = cap->name; @@ -818,6 +864,11 @@ void LiveCapture::on_previewSplit_splitterMoved(int pos, int index) m_IgnorePreviewToggle = false; } +void LiveCapture::on_apiIcon_clicked(QMouseEvent *event) +{ + QDesktopServices::openUrl(QUrl(lit("https://renderdoc.org/docs/in_application_api.html"))); +} + void LiveCapture::captures_keyPress(QKeyEvent *e) { if(e->key() == Qt::Key_Delete) @@ -1018,7 +1069,7 @@ void LiveCapture::connectionThreadEntry() { GUIInvoke::call([this]() { setTitle(tr("Connection failed")); - ui->connectionStatus->setText(tr("Connection failed")); + ui->connectionStatus->setText(tr("Failed")); ui->connectionIcon->setPixmap(Pixmaps::del(ui->connectionIcon)); connectionClosed(); @@ -1028,25 +1079,16 @@ void LiveCapture::connectionThreadEntry() } GUIInvoke::call([this]() { - QString api = QString::fromUtf8(m_Connection->GetAPI()); - if(api.isEmpty()) - api = tr("No API detected"); - - QString target = QString::fromUtf8(m_Connection->GetTarget()); uint32_t pid = m_Connection->GetPID(); - - if(pid == 0) - { - ui->connectionStatus->setText(tr("Connection established to %1 (%2)").arg(target).arg(api)); - setTitle(target); - } - else - { - ui->connectionStatus->setText( - tr("Connection established to %1 [PID %2] (%3)").arg(target).arg(pid).arg(api)); + QString target = QString::fromUtf8(m_Connection->GetTarget()); + if(pid) setTitle(QFormatStr("%1 [PID %2]").arg(target).arg(pid)); - } + else + setTitle(target); + + ui->target->setText(windowTitle()); ui->connectionIcon->setPixmap(Pixmaps::connect(ui->connectionIcon)); + ui->connectionStatus->setText(tr("Established")); }); while(m_Connection && m_Connection->Connected()) @@ -1095,28 +1137,37 @@ void LiveCapture::connectionThreadEntry() bool presenting = msg.apiUse.presenting; bool supported = msg.apiUse.supported; GUIInvoke::call([this, api, presenting, supported]() { - QString target = QString::fromUtf8(m_Connection->GetTarget()); - uint32_t pid = m_Connection->GetPID(); + m_APIs[api] = APIStatus(presenting, supported); - if(pid == 0) + if(presenting && supported) { - ui->connectionStatus->setText(tr("Connection established to %1 (%2)").arg(target).arg(api)); - setTitle(target); + ui->triggerCapture->setEnabled(true); + ui->queueCap->setEnabled(true); } - else - { - ui->connectionStatus->setText( - tr("Connection established to %1 [PID %2] (%3)").arg(target).arg(pid).arg(api)); - setTitle(QFormatStr("%1 [PID %2]").arg(target).arg(pid)); - } - ui->connectionIcon->setPixmap(Pixmaps::connect(ui->connectionIcon)); + + updateAPIStatus(); }); } if(msg.type == TargetControlMessageType::CaptureProgress) { float progress = msg.capProgress; - GUIInvoke::call([this, progress]() {}); + GUIInvoke::call([this, progress]() { + + if(progress >= 0.0f && progress < 1.0f) + { + ui->captureProgressLabel->setVisible(true); + ui->captureProgress->setVisible(true); + ui->captureProgress->setMaximum(1000); + ui->captureProgress->setValue(1000 * progress); + } + else + { + ui->captureProgressLabel->setVisible(false); + ui->captureProgress->setVisible(false); + } + + }); } if(msg.type == TargetControlMessageType::NewCapture) @@ -1143,7 +1194,7 @@ void LiveCapture::connectionThreadEntry() uint32_t capID = msg.newCapture.captureId; QString path = msg.newCapture.path; - GUIInvoke::call([=]() { captureCopied(capID, path); }); + GUIInvoke::call([this, capID, path]() { captureCopied(capID, path); }); } if(msg.type == TargetControlMessageType::NewChild) @@ -1163,7 +1214,7 @@ void LiveCapture::connectionThreadEntry() } GUIInvoke::call([this]() { - ui->connectionStatus->setText(tr("Connection closed")); + ui->connectionStatus->setText(tr("Closed")); ui->connectionIcon->setPixmap(Pixmaps::disconnect(ui->connectionIcon)); ui->numFrames->setEnabled(false); @@ -1172,6 +1223,9 @@ void LiveCapture::connectionThreadEntry() ui->triggerCapture->setEnabled(false); ui->queueCap->setEnabled(false); + ui->apiStatus->setText(tr("None")); + ui->apiIcon->setVisible(false); + connectionClosed(); }); } diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.h b/qrenderdoc/Windows/Dialogs/LiveCapture.h index 87944e5dd..108ecbb1e 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.h +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.h @@ -72,6 +72,7 @@ private slots: void on_triggerCapture_clicked(); void on_queueCap_clicked(); void on_previewSplit_splitterMoved(int pos, int index); + void on_apiIcon_clicked(QMouseEvent *event); // manual slots void captures_keyPress(QKeyEvent *e); @@ -116,12 +117,22 @@ private: bool added = false; }; + struct APIStatus + { + APIStatus() = default; + APIStatus(bool p, bool s) : presenting(p), supported(s) {} + bool presenting = false; + bool supported = false; + }; + Capture *GetCapture(QListWidgetItem *item); void AddCapture(QListWidgetItem *item, Capture *cap); QString MakeText(Capture *cap); QImage MakeThumb(const QImage &screenshot); + void updateAPIStatus(); + void connectionThreadEntry(); void captureCopied(uint32_t ID, const QString &localPath); void captureAdded(uint32_t ID, const QString &executable, const QString &api, @@ -177,4 +188,5 @@ private: QMutex m_ChildrenLock; QList m_Children; + QMap m_APIs; }; diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.ui b/qrenderdoc/Windows/Dialogs/LiveCapture.ui index d069bcdd1..53c67dad9 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.ui +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.ui @@ -6,7 +6,7 @@ 0 0 - 749 + 680 483 @@ -27,19 +27,13 @@ 3 - + 0 0 - - QFrame::NoFrame - - - QFrame::Plain - 0 @@ -54,158 +48,259 @@ 0 - - - - - - :/hourglass.png + + + Status + + + + + Target: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + None + + + Qt::RichText + + + + + + + Connecting + + + + + + + + + + + + + + Capture in Progress: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Connection Status: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + API: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + :/hourglass.png + + + + + + + + 0 + 0 + + + + PointingHandCursor + + + <p>An API in use is not presenting to a window. This commonly means the API rendering is happening to off-screen targets and either nothing is displayed, or the results are displayed using some other mechanism.</p> + +<p>Without the boundary of a frame, RenderDoc cannot capture by default since it can't tell where to start and stop.</p> + +<p>You can use RenderDoc's In-application API to manually provide markers about where to start and stop the frame capture.</p> + +<p>Click on the icon for more information about this API.</p> + + + :/information.png + + + + + + + + 0 + 0 + + + + + - - - Connecting... + + + Tools + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + 10000.000000000000000 + + + + + + + Queue Capture + + + + + + + + 0 + 0 + + + + secs + + + 0 + + + 120.000000000000000 + + + 0.000000000000000 + + + + + + + + 45 + 0 + + + + 0 + + + 1.000000000000000 + + + 4.000000000000000 + + + + + + + Capture Delay + + + + + + + + 0 + 0 + + + + # Frames: + + + + + + + Trigger Capture + + + + + + + Capture Frame # + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 0 - 0 - - - - Tools - - - - - - Queue Capture - - - - - - - - 0 - 0 - - - - secs - - - 0 - - - 120.000000000000000 - - - 0.000000000000000 - - - - - - - - 45 - 0 - - - - 0 - - - 1.000000000000000 - - - 4.000000000000000 - - - - - - - Capture Delay - - - - - - - - 0 - 0 - - - - # Frames: - - - - - - - Trigger Capture - - - - - - - Capture Frame # - - - - Qt::Horizontal - 40 + 75 20 - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - 10000.000000000000000 - - -