From 369d93b99c6c3fa129599048e894aeca78986db4 Mon Sep 17 00:00:00 2001 From: "tabi.katalin" Date: Wed, 19 Sep 2018 08:47:20 +0200 Subject: [PATCH] Cycle active window with button A new button is added to the UI so that we can cycle the currently active window when there are more windows to capture. It's like pressing the F11 button but it works on Android too. --- qrenderdoc/Windows/Dialogs/LiveCapture.cpp | 13 ++++++ qrenderdoc/Windows/Dialogs/LiveCapture.h | 1 + qrenderdoc/Windows/Dialogs/LiveCapture.ui | 23 ++++++---- renderdoc/api/replay/control_types.h | 3 ++ renderdoc/api/replay/renderdoc_replay.h | 3 ++ renderdoc/api/replay/replay_enums.h | 1 + renderdoc/core/core.cpp | 47 +++++++++++---------- renderdoc/core/core.h | 2 + renderdoc/core/target_control.cpp | 49 +++++++++++++++++++++- 9 files changed, 112 insertions(+), 30 deletions(-) diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.cpp b/qrenderdoc/Windows/Dialogs/LiveCapture.cpp index ac7a90159..a5c8687b4 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.cpp +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.cpp @@ -122,6 +122,7 @@ LiveCapture::LiveCapture(ICaptureContext &ctx, const QString &hostname, const QS ui->triggerDelayedCapture->setEnabled(false); ui->triggerImmediateCapture->setEnabled(false); ui->queueCap->setEnabled(false); + ui->cycleActiveWindow->setEnabled(false); ui->target->setText(QString()); @@ -282,6 +283,11 @@ void LiveCapture::on_triggerImmediateCapture_clicked() m_CaptureNumFrames = (int)ui->numFrames->value(); } +void LiveCapture::on_cycleActiveWindow_clicked() +{ + m_Connection->CycleActiveWindow(); +} + void LiveCapture::on_triggerDelayedCapture_clicked() { if(ui->captureDelay->value() == 0.0) @@ -1257,6 +1263,12 @@ void LiveCapture::connectionThreadEntry() } } } + + if(msg.type == TargetControlMessageType::CapturableWindowCount) + { + uint32_t windows = msg.capturableWindowCount; + GUIInvoke::call(this, [this, windows]() { ui->cycleActiveWindow->setEnabled(windows > 1); }); + } } GUIInvoke::call(this, [this]() { @@ -1269,6 +1281,7 @@ void LiveCapture::connectionThreadEntry() ui->triggerDelayedCapture->setEnabled(false); ui->triggerImmediateCapture->setEnabled(false); ui->queueCap->setEnabled(false); + ui->cycleActiveWindow->setEnabled(false); ui->apiStatus->setText(tr("None")); ui->apiIcon->setVisible(false); diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.h b/qrenderdoc/Windows/Dialogs/LiveCapture.h index 35adfc518..32aa8d8a0 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.h +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.h @@ -70,6 +70,7 @@ private slots: void on_captures_itemActivated(QListWidgetItem *item); void on_childProcesses_itemActivated(QListWidgetItem *item); void on_triggerImmediateCapture_clicked(); + void on_cycleActiveWindow_clicked(); void on_triggerDelayedCapture_clicked(); void on_queueCap_clicked(); void on_previewSplit_splitterMoved(int pos, int index); diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.ui b/qrenderdoc/Windows/Dialogs/LiveCapture.ui index b7cba0995..58d10eb9c 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.ui +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.ui @@ -190,7 +190,14 @@ Tools - + + + + Capture Frame(s) Immediately + + + + @@ -212,7 +219,7 @@ - + Frame @@ -225,14 +232,14 @@ - + Capture After Delay: - + Capture Specific Frame(s): @@ -267,7 +274,7 @@ - + Qt::Vertical @@ -280,10 +287,10 @@ - - + + - Capture Frame(s) Immediately + Cycle Active Window diff --git a/renderdoc/api/replay/control_types.h b/renderdoc/api/replay/control_types.h index fa05c0ea4..1aca56204 100644 --- a/renderdoc/api/replay/control_types.h +++ b/renderdoc/api/replay/control_types.h @@ -542,6 +542,9 @@ When valid, will be in the range of 0.0 to 1.0 (0 - 100%). If not valid when a c or has finished, it will be -1.0 )"); float capProgress = -1.0f; + + DOCUMENT("The number of the capturable windows"); + uint32_t capturableWindowCount = 0; }; DECLARE_REFLECTION_STRUCT(TargetControlMessage); diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index cc40325cd..d964a7b10 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -1342,6 +1342,9 @@ The details of the types of messages that can be received are listed under )"); virtual TargetControlMessage ReceiveMessage(RENDERDOC_ProgressCallback progress) = 0; + DOCUMENT("Cycle the currently active window if there are more windows to capture."); + virtual void CycleActiveWindow() = 0; + protected: ITargetControl() = default; ~ITargetControl() = default; diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index 7a2c39b9f..5c5dd418e 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -3143,6 +3143,7 @@ enum class TargetControlMessageType : uint32_t RegisterAPI, NewChild, CaptureProgress, + CapturableWindowCount }; DECLARE_REFLECTION_ENUM(TargetControlMessageType); diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index 378953f51..3bf1bce50 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -542,27 +542,7 @@ void RenderDoc::Tick() if(!prev_focus && cur_focus) { - m_Cap = 0; - - // can only shift focus if we have multiple windows - if(m_WindowFrameCapturers.size() > 1) - { - for(auto it = m_WindowFrameCapturers.begin(); it != m_WindowFrameCapturers.end(); ++it) - { - if(it->first == m_ActiveWindow) - { - auto nextit = it; - ++nextit; - - if(nextit != m_WindowFrameCapturers.end()) - m_ActiveWindow = nextit->first; - else - m_ActiveWindow = m_WindowFrameCapturers.begin()->first; - - break; - } - } - } + CycleActiveWindow(); } if(!prev_cap && cur_cap) { @@ -573,6 +553,31 @@ void RenderDoc::Tick() prev_cap = cur_cap; } +void RenderDoc::CycleActiveWindow() +{ + m_Cap = 0; + + // can only shift focus if we have multiple windows + if(m_WindowFrameCapturers.size() > 1) + { + for(auto it = m_WindowFrameCapturers.begin(); it != m_WindowFrameCapturers.end(); ++it) + { + if(it->first == m_ActiveWindow) + { + auto nextit = it; + ++nextit; + + if(nextit != m_WindowFrameCapturers.end()) + m_ActiveWindow = nextit->first; + else + m_ActiveWindow = m_WindowFrameCapturers.begin()->first; + + break; + } + } + } +} + string RenderDoc::GetOverlayText(RDCDriver driver, uint32_t frameNumber, int flags) { const bool activeWindow = (flags & eOverlay_ActiveWindow); diff --git a/renderdoc/core/core.h b/renderdoc/core/core.h index fb85a3700..b0ac732b8 100644 --- a/renderdoc/core/core.h +++ b/renderdoc/core/core.h @@ -536,6 +536,8 @@ public: string GetOverlayText(RDCDriver driver, uint32_t frameNumber, int flags); + void CycleActiveWindow(); + uint32_t GetCapturableWindowCount() { return (uint32_t)m_WindowFrameCapturers.size(); } private: RenderDoc(); ~RenderDoc(); diff --git a/renderdoc/core/target_control.cpp b/renderdoc/core/target_control.cpp index 2be440fd3..bcf83ac74 100644 --- a/renderdoc/core/target_control.cpp +++ b/renderdoc/core/target_control.cpp @@ -30,7 +30,7 @@ #include "os/os_specific.h" #include "serialise/serialiser.h" -static const uint32_t TargetControlProtocolVersion = 3; +static const uint32_t TargetControlProtocolVersion = 4; static bool IsProtocolVersionSupported(const uint32_t protocolVersion) { @@ -38,6 +38,10 @@ static bool IsProtocolVersionSupported(const uint32_t protocolVersion) if(protocolVersion == 2) return true; + // 3 -> 4 added active window cycle and window count packets + if(protocolVersion == 3) + return true; + if(protocolVersion == TargetControlProtocolVersion) return true; @@ -57,6 +61,8 @@ enum PacketType : uint32_t ePacket_QueueCapture, ePacket_NewChild, ePacket_CaptureProgress, + ePacket_CycleActiveWindow, + ePacket_CapturableWindowCount }; DECLARE_REFLECTION_ENUM(PacketType); @@ -77,6 +83,8 @@ std::string DoStringise(const PacketType &el) STRINGISE_ENUM_NAMED(ePacket_QueueCapture, "Queue Capture"); STRINGISE_ENUM_NAMED(ePacket_NewChild, "New Child"); STRINGISE_ENUM_NAMED(ePacket_CaptureProgress, "Capture Progress"); + STRINGISE_ENUM_NAMED(ePacket_CycleActiveWindow, "Cycle Active Window"); + STRINGISE_ENUM_NAMED(ePacket_CapturableWindowCount, "Capturable Window Count"); } END_ENUM_STRINGISE(); } @@ -131,6 +139,7 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli std::vector > children; std::map drivers; float prevCaptureProgress = captureProgress; + uint32_t prevWindows = 0; while(client) { @@ -148,6 +157,8 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli std::vector caps = RenderDoc::Inst().GetCaptures(); std::vector > childprocs = RenderDoc::Inst().GetChildProcesses(); + uint32_t curWindows = RenderDoc::Inst().GetCapturableWindowCount(); + if(curdrivers != drivers) { // find the first difference, either a new key or a key with a different value, and send it. @@ -242,6 +253,16 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli } } } + else if(version >= 4 && prevWindows != curWindows) + { + prevWindows = curWindows; + + WRITE_DATA_SCOPE(); + { + SCOPED_SERIALISE_CHUNK(ePacket_CapturableWindowCount); + SERIALISE_ELEMENT(curWindows); + } + } if(curtime > pingtime) { @@ -321,6 +342,10 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli RenderDoc::Inst().MarkCaptureRetrieved(id); } } + else if(type == ePacket_CycleActiveWindow) + { + RenderDoc::Inst().CycleActiveWindow(); + } reader.EndChunk(); @@ -602,6 +627,18 @@ public: SAFE_DELETE(m_Socket); } + void CycleActiveWindow() + { + if(m_Version < 4) + return; + + WRITE_DATA_SCOPE(); + SCOPED_SERIALISE_CHUNK(ePacket_CycleActiveWindow); + + if(ser.IsErrored()) + SAFE_DELETE(m_Socket); + } + TargetControlMessage ReceiveMessage(RENDERDOC_ProgressCallback progress) { TargetControlMessage msg; @@ -778,6 +815,16 @@ public: reader.EndChunk(); return msg; } + else if(type == ePacket_CapturableWindowCount) + { + msg.type = TargetControlMessageType::CapturableWindowCount; + uint32_t windows = 0; + READ_DATA_SCOPE(); + SERIALISE_ELEMENT(windows); + msg.capturableWindowCount = windows; + reader.EndChunk(); + return msg; + } else { RDCERR("Unexpected packed received: %d", type);