mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 01:20:42 +00:00
Add a menu item to do nothing but replay the capture in a tight loop.
This commit is contained in:
@@ -606,6 +606,9 @@ struct IReplayManager
|
||||
DOCUMENT("Ping the remote server to ensure the connection is still alive.");
|
||||
virtual void PingRemote() = 0;
|
||||
|
||||
DOCUMENT("Cancels the active replay loop. See :meth:`~renderdoc.ReplayController.ReplayLoop`.");
|
||||
virtual void CancelReplayLoop() = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieves the host that the manager is currently connected to.
|
||||
|
||||
:return: The host connected to, or ``None`` if no connection is active.
|
||||
|
||||
@@ -274,6 +274,11 @@ void ReplayManager::BlockInvoke(ReplayManager::InvokeCallback m)
|
||||
delete cmd;
|
||||
}
|
||||
|
||||
void ReplayManager::CancelReplayLoop()
|
||||
{
|
||||
m_Renderer->CancelReplayLoop();
|
||||
}
|
||||
|
||||
void ReplayManager::CloseThread()
|
||||
{
|
||||
m_Running = false;
|
||||
@@ -393,11 +398,11 @@ void ReplayManager::PushInvoke(ReplayManager::InvokeHandle *cmd)
|
||||
|
||||
void ReplayManager::run()
|
||||
{
|
||||
IReplayController *renderer = NULL;
|
||||
m_Renderer = NULL;
|
||||
|
||||
if(m_Remote)
|
||||
{
|
||||
std::tie(m_CreateStatus, renderer) =
|
||||
std::tie(m_CreateStatus, m_Renderer) =
|
||||
m_Remote->OpenCapture(~0U, m_Logfile.toUtf8().data(), m_Progress);
|
||||
}
|
||||
else
|
||||
@@ -407,12 +412,12 @@ void ReplayManager::run()
|
||||
m_CreateStatus = file->OpenStatus();
|
||||
|
||||
if(m_CreateStatus == ReplayStatus::Succeeded)
|
||||
std::tie(m_CreateStatus, renderer) = file->OpenCapture(m_Progress);
|
||||
std::tie(m_CreateStatus, m_Renderer) = file->OpenCapture(m_Progress);
|
||||
|
||||
file->Shutdown();
|
||||
}
|
||||
|
||||
if(renderer == NULL)
|
||||
if(m_Renderer == NULL)
|
||||
return;
|
||||
|
||||
qInfo() << "QRenderDoc - renderer created for" << m_Logfile;
|
||||
@@ -439,7 +444,7 @@ void ReplayManager::run()
|
||||
continue;
|
||||
|
||||
if(cmd->method != NULL)
|
||||
cmd->method(renderer);
|
||||
cmd->method(m_Renderer);
|
||||
|
||||
// if it's a throwaway command, delete it
|
||||
if(cmd->selfdelete)
|
||||
@@ -471,7 +476,7 @@ void ReplayManager::run()
|
||||
|
||||
// close the core renderer
|
||||
if(m_Remote)
|
||||
m_Remote->CloseCapture(renderer);
|
||||
m_Remote->CloseCapture(m_Renderer);
|
||||
else
|
||||
renderer->Shutdown();
|
||||
m_Renderer->Shutdown();
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ public:
|
||||
void AsyncInvoke(InvokeCallback m);
|
||||
void BlockInvoke(InvokeCallback m);
|
||||
|
||||
void CancelReplayLoop();
|
||||
|
||||
void CloseThread();
|
||||
|
||||
ReplayStatus ConnectToRemoteServer(RemoteHost *host);
|
||||
@@ -107,6 +109,8 @@ private:
|
||||
QQueue<InvokeHandle *> m_RenderQueue;
|
||||
QWaitCondition m_RenderCondition;
|
||||
|
||||
IReplayController *m_Renderer = NULL;
|
||||
|
||||
void PushInvoke(InvokeHandle *cmd);
|
||||
|
||||
int m_ProxyRenderer;
|
||||
|
||||
@@ -165,6 +165,7 @@ MainWindow::MainWindow(ICaptureContext &ctx) : QMainWindow(NULL), ui(new Ui::Mai
|
||||
return m_Ctx.CreateBuiltinWindow(objectName);
|
||||
});
|
||||
|
||||
ui->action_Start_Replay_Loop->setEnabled(false);
|
||||
ui->action_Resolve_Symbols->setEnabled(false);
|
||||
ui->action_Resolve_Symbols->setText(tr("Resolve Symbols"));
|
||||
|
||||
@@ -1246,6 +1247,8 @@ void MainWindow::OnLogfileLoaded()
|
||||
|
||||
statusProgress->setVisible(false);
|
||||
|
||||
ui->action_Start_Replay_Loop->setEnabled(true);
|
||||
|
||||
setLogHasErrors(!m_Ctx.DebugMessages().empty());
|
||||
|
||||
m_Ctx.Replay().AsyncInvoke([this](IReplayController *r) {
|
||||
@@ -1272,6 +1275,8 @@ void MainWindow::OnLogfileClosed()
|
||||
ui->action_Save_Log->setEnabled(false);
|
||||
ui->action_Close_Log->setEnabled(false);
|
||||
|
||||
ui->action_Start_Replay_Loop->setEnabled(false);
|
||||
|
||||
contextChooser->setEnabled(true);
|
||||
|
||||
statusText->setText(QString());
|
||||
@@ -1523,6 +1528,66 @@ void MainWindow::on_action_Resolve_Symbols_triggered()
|
||||
m_Ctx.GetAPIInspector()->Refresh();
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Start_Replay_Loop_triggered()
|
||||
{
|
||||
if(!m_Ctx.LogLoaded())
|
||||
return;
|
||||
|
||||
QDialog popup;
|
||||
popup.setWindowFlags(popup.windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
popup.setWindowIcon(windowIcon());
|
||||
|
||||
const TextureDescription *displayTex = NULL;
|
||||
|
||||
const DrawcallDescription *lastDraw = m_Ctx.GetLastDrawcall();
|
||||
|
||||
displayTex = m_Ctx.GetTexture(lastDraw->copyDestination);
|
||||
if(!displayTex)
|
||||
displayTex = m_Ctx.GetTexture(lastDraw->outputs[0]);
|
||||
|
||||
if(!displayTex)
|
||||
{
|
||||
// if no texture was bound, then use the first colour swapbuffer
|
||||
for(const TextureDescription &tex : m_Ctx.GetTextures())
|
||||
{
|
||||
if((tex.creationFlags & TextureCategory::SwapBuffer) &&
|
||||
tex.format.compType != CompType::Depth && tex.format.specialFormat != SpecialFormat::D16S8 &&
|
||||
tex.format.specialFormat != SpecialFormat::D24S8 &&
|
||||
tex.format.specialFormat != SpecialFormat::D32S8)
|
||||
{
|
||||
displayTex = &tex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResourceId id;
|
||||
|
||||
if(displayTex)
|
||||
{
|
||||
id = displayTex->ID;
|
||||
popup.resize((int)displayTex->width, (int)displayTex->height);
|
||||
popup.setWindowTitle(
|
||||
tr("Looping replay of %1 Displaying %2").arg(m_Ctx.LogFilename()).arg(ToQStr(displayTex->name)));
|
||||
}
|
||||
else
|
||||
{
|
||||
popup.resize(100, 100);
|
||||
popup.setWindowTitle(
|
||||
tr("Looping replay of %1 Displaying %2").arg(m_Ctx.LogFilename()).arg(tr("nothing")));
|
||||
}
|
||||
|
||||
WindowingSystem winSys = m_Ctx.CurWindowingSystem();
|
||||
void *winData = m_Ctx.FillWindowingData(popup.winId());
|
||||
|
||||
m_Ctx.Replay().AsyncInvoke(
|
||||
[winSys, winData, id](IReplayController *r) { r->ReplayLoop(winSys, winData, id); });
|
||||
|
||||
RDDialog::show(&popup);
|
||||
|
||||
m_Ctx.Replay().CancelReplayLoop();
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Attach_to_Running_Instance_triggered()
|
||||
{
|
||||
on_action_Manage_Remote_Servers_triggered();
|
||||
|
||||
@@ -113,6 +113,7 @@ private slots:
|
||||
void on_action_Python_Shell_triggered();
|
||||
void on_action_Inject_into_Process_triggered();
|
||||
void on_action_Resolve_Symbols_triggered();
|
||||
void on_action_Start_Replay_Loop_triggered();
|
||||
void on_action_Attach_to_Running_Instance_triggered();
|
||||
void on_action_Manage_Remote_Servers_triggered();
|
||||
void on_action_Settings_triggered();
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1200</width>
|
||||
<height>26</height>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_Tools">
|
||||
@@ -50,9 +50,11 @@
|
||||
<string>&Tools</string>
|
||||
</property>
|
||||
<addaction name="action_Resolve_Symbols"/>
|
||||
<addaction name="action_Start_Replay_Loop"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Settings"/>
|
||||
<addaction name="action_Manage_Remote_Servers"/>
|
||||
<addaction name="separator"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_File">
|
||||
<property name="title">
|
||||
@@ -398,6 +400,11 @@
|
||||
<string>&Launch Application</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Start_Replay_Loop">
|
||||
<property name="text">
|
||||
<string>Start Replay &Loop</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
||||
@@ -444,6 +444,22 @@ struct IReplayController
|
||||
)");
|
||||
virtual void ShutdownOutput(IReplayOutput *output) = 0;
|
||||
|
||||
DOCUMENT(R"(Goes into a blocking loop, repeatedly replaying the open capture as fast as possible,
|
||||
displaying the selected texture in a default unscaled manner to the given output window.
|
||||
|
||||
The function won't return until :meth:`CancelLoop` is called. Since this function is blocking, that
|
||||
function must be called from another thread.
|
||||
|
||||
:param WindowingSystem system: The type of native window handle data being provided
|
||||
:param data: The native window data, in a format defined by the system
|
||||
:type data: opaque void * pointer
|
||||
:param ResourceId texid: The id of the texture to display.
|
||||
)");
|
||||
virtual void ReplayLoop(WindowingSystem system, void *data, ResourceId texid) = 0;
|
||||
|
||||
DOCUMENT("Cancels a replay loop begun in :meth:`ReplayLoop`. Does nothing if no loop is active.");
|
||||
virtual void CancelReplayLoop() = 0;
|
||||
|
||||
DOCUMENT("Notify the interface that the file it has open has been changed on disk.");
|
||||
virtual void FileChanged() = 0;
|
||||
|
||||
|
||||
@@ -1398,6 +1398,58 @@ rdctype::array<WindowingSystem> ReplayController::GetSupportedWindowSystems()
|
||||
return m_pDevice->GetSupportedWindowSystems();
|
||||
}
|
||||
|
||||
void ReplayController::ReplayLoop(WindowingSystem system, void *data, ResourceId texid)
|
||||
{
|
||||
ReplayOutput *output = CreateOutput(system, data, ReplayOutputType::Texture);
|
||||
|
||||
TextureDisplay d;
|
||||
d.texid = texid;
|
||||
d.mip = 0;
|
||||
d.sampleIdx = ~0U;
|
||||
d.overlay = DebugOverlay::NoOverlay;
|
||||
d.typeHint = CompType::Typeless;
|
||||
d.HDRMul = -1.0f;
|
||||
d.linearDisplayAsGamma = true;
|
||||
d.FlipY = false;
|
||||
d.rangemin = 0.0f;
|
||||
d.rangemax = 1.0f;
|
||||
d.scale = 1.0f;
|
||||
d.offx = 0.0f;
|
||||
d.offy = 0.0f;
|
||||
d.sliceFace = 0;
|
||||
d.rawoutput = false;
|
||||
d.Red = d.Green = d.Blue = true;
|
||||
d.Alpha = false;
|
||||
output->SetTextureDisplay(d);
|
||||
|
||||
m_ReplayLoopCancel = 0;
|
||||
m_ReplayLoopFinished = 0;
|
||||
|
||||
while(Atomic::CmpExch32(&m_ReplayLoopCancel, 0, 0) == 0)
|
||||
{
|
||||
m_pDevice->ReplayLog(10000000, eReplay_Full);
|
||||
|
||||
output->Display();
|
||||
}
|
||||
|
||||
// restore back to where we were
|
||||
m_pDevice->ReplayLog(m_EventID, eReplay_Full);
|
||||
|
||||
ShutdownOutput(output);
|
||||
|
||||
// mark that the loop is finished
|
||||
Atomic::Inc32(&m_ReplayLoopFinished);
|
||||
}
|
||||
|
||||
void ReplayController::CancelReplayLoop()
|
||||
{
|
||||
Atomic::Inc32(&m_ReplayLoopCancel);
|
||||
|
||||
// wait for it to actually finish before returning
|
||||
while(Atomic::CmpExch32(&m_ReplayLoopFinished, 0, 0) == 0)
|
||||
Threading::Sleep(1);
|
||||
}
|
||||
|
||||
ReplayOutput *ReplayController::CreateOutput(WindowingSystem system, void *data, ReplayOutputType type)
|
||||
{
|
||||
ReplayOutput *out = new ReplayOutput(this, system, data, type);
|
||||
@@ -1672,6 +1724,18 @@ extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_ShutdownOutput(IReplay
|
||||
rend->ShutdownOutput(output);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_ReplayLoop(IReplayController *rend,
|
||||
WindowingSystem system,
|
||||
void *data, ResourceId texid)
|
||||
{
|
||||
rend->ReplayLoop(system, data, texid);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_CancelReplayLoop(IReplayController *rend)
|
||||
{
|
||||
rend->CancelReplayLoop();
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_FileChanged(IReplayController *rend)
|
||||
{
|
||||
rend->FileChanged();
|
||||
|
||||
@@ -191,6 +191,9 @@ public:
|
||||
|
||||
rdctype::array<WindowingSystem> GetSupportedWindowSystems();
|
||||
|
||||
void ReplayLoop(WindowingSystem system, void *data, ResourceId texid);
|
||||
void CancelReplayLoop();
|
||||
|
||||
ReplayOutput *CreateOutput(WindowingSystem, void *data, ReplayOutputType type);
|
||||
|
||||
void ShutdownOutput(IReplayOutput *output);
|
||||
@@ -205,6 +208,9 @@ private:
|
||||
FrameRecord m_FrameRecord;
|
||||
vector<DrawcallDescription *> m_Drawcalls;
|
||||
|
||||
volatile int32_t m_ReplayLoopCancel = 0;
|
||||
volatile int32_t m_ReplayLoopFinished = 0;
|
||||
|
||||
uint32_t m_EventID;
|
||||
|
||||
D3D11Pipe::State m_D3D11PipelineState;
|
||||
|
||||
@@ -410,6 +410,14 @@ namespace renderdocui.Code
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelReplayLoop()
|
||||
{
|
||||
if (m_Thread == null || !Running)
|
||||
return;
|
||||
|
||||
m_Renderer.CancelReplayLoop();
|
||||
}
|
||||
|
||||
public ReplayCreateException InitException = null;
|
||||
|
||||
public void CloseThreadSync()
|
||||
@@ -608,12 +616,14 @@ namespace renderdocui.Code
|
||||
renderer.Shutdown();
|
||||
}
|
||||
|
||||
private ReplayRenderer m_Renderer;
|
||||
|
||||
private void RunThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
ReplayRenderer renderer = CreateReplayRenderer();
|
||||
if(renderer != null)
|
||||
m_Renderer = CreateReplayRenderer();
|
||||
if(m_Renderer != null)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("Renderer created");
|
||||
|
||||
@@ -644,7 +654,7 @@ namespace renderdocui.Code
|
||||
{
|
||||
try
|
||||
{
|
||||
m_current.method(renderer);
|
||||
m_current.method(m_Renderer);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -653,7 +663,7 @@ namespace renderdocui.Code
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current.method(renderer);
|
||||
m_current.method(m_Renderer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -669,7 +679,7 @@ namespace renderdocui.Code
|
||||
m_renderQueue.Clear();
|
||||
}
|
||||
|
||||
DestroyReplayRenderer(renderer);
|
||||
DestroyReplayRenderer(m_Renderer);
|
||||
}
|
||||
}
|
||||
catch (ReplayCreateException ex)
|
||||
|
||||
@@ -285,6 +285,11 @@ namespace renderdoc
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void ReplayRenderer_ShutdownOutput(IntPtr real, IntPtr replayOutput);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern IntPtr ReplayRenderer_ReplayLoop(IntPtr real, UInt32 windowSystem, IntPtr WindowHandle, ResourceId texid);
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern IntPtr ReplayRenderer_CancelReplayLoop(IntPtr real);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void ReplayRenderer_FileChanged(IntPtr real);
|
||||
|
||||
@@ -396,6 +401,20 @@ namespace renderdoc
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void ReplayLoop(IntPtr WindowHandle, ResourceId texid)
|
||||
{
|
||||
if (WindowHandle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
// 1 == eWindowingSystem_Win32
|
||||
ReplayRenderer_ReplayLoop(m_Real, 1u, WindowHandle, texid);
|
||||
}
|
||||
|
||||
public void CancelReplayLoop()
|
||||
{
|
||||
ReplayRenderer_CancelReplayLoop(m_Real);
|
||||
}
|
||||
|
||||
public ReplayOutput CreateOutput(IntPtr WindowHandle, OutputType type)
|
||||
{
|
||||
// 0 == eWindowingSystem_Unknown
|
||||
|
||||
+25
-15
@@ -95,6 +95,7 @@
|
||||
this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.manageRemote = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.startAndroidRemoteServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.viewDocsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@@ -119,7 +120,7 @@
|
||||
this.statusProgress = new System.Windows.Forms.ToolStripProgressBar();
|
||||
this.dockPanel = new WeifenLuo.WinFormsUI.Docking.DockPanel();
|
||||
this.saveDialog = new System.Windows.Forms.SaveFileDialog();
|
||||
this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.startReplayLoopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.toolStripContainer1.BottomToolStripPanel.SuspendLayout();
|
||||
this.toolStripContainer1.ContentPanel.SuspendLayout();
|
||||
@@ -516,6 +517,7 @@
|
||||
//
|
||||
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.resolveSymbolsToolStripMenuItem,
|
||||
this.startReplayLoopToolStripMenuItem,
|
||||
this.toolStripSeparator11,
|
||||
this.optionsToolStripMenuItem,
|
||||
this.manageRemote,
|
||||
@@ -528,29 +530,41 @@
|
||||
// resolveSymbolsToolStripMenuItem
|
||||
//
|
||||
this.resolveSymbolsToolStripMenuItem.Name = "resolveSymbolsToolStripMenuItem";
|
||||
this.resolveSymbolsToolStripMenuItem.Size = new System.Drawing.Size(192, 22);
|
||||
this.resolveSymbolsToolStripMenuItem.Size = new System.Drawing.Size(213, 22);
|
||||
this.resolveSymbolsToolStripMenuItem.Text = "&Resolve Symbols";
|
||||
this.resolveSymbolsToolStripMenuItem.Click += new System.EventHandler(this.resolveSymbolsToolStripMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator11
|
||||
//
|
||||
this.toolStripSeparator11.Name = "toolStripSeparator11";
|
||||
this.toolStripSeparator11.Size = new System.Drawing.Size(189, 6);
|
||||
this.toolStripSeparator11.Size = new System.Drawing.Size(210, 6);
|
||||
//
|
||||
// optionsToolStripMenuItem
|
||||
//
|
||||
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
||||
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(192, 22);
|
||||
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(213, 22);
|
||||
this.optionsToolStripMenuItem.Text = "&Options";
|
||||
this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click);
|
||||
//
|
||||
// manageRemote
|
||||
//
|
||||
this.manageRemote.Name = "manageRemote";
|
||||
this.manageRemote.Size = new System.Drawing.Size(192, 22);
|
||||
this.manageRemote.Size = new System.Drawing.Size(213, 22);
|
||||
this.manageRemote.Text = "&Manage Remote Servers";
|
||||
this.manageRemote.Click += new System.EventHandler(this.manageRemote_Click);
|
||||
//
|
||||
// toolStripSeparator13
|
||||
//
|
||||
this.toolStripSeparator13.Name = "toolStripSeparator13";
|
||||
this.toolStripSeparator13.Size = new System.Drawing.Size(210, 6);
|
||||
//
|
||||
// startAndroidRemoteServerToolStripMenuItem
|
||||
//
|
||||
this.startAndroidRemoteServerToolStripMenuItem.Name = "startAndroidRemoteServerToolStripMenuItem";
|
||||
this.startAndroidRemoteServerToolStripMenuItem.Size = new System.Drawing.Size(213, 22);
|
||||
this.startAndroidRemoteServerToolStripMenuItem.Text = "Start Android Remote Server";
|
||||
this.startAndroidRemoteServerToolStripMenuItem.Click += new System.EventHandler(this.startAndroidRemoteServerToolStripMenuItem_Click);
|
||||
//
|
||||
// helpToolStripMenuItem
|
||||
//
|
||||
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
@@ -808,17 +822,12 @@
|
||||
this.saveDialog.Filter = "Log Files (*.rdc)|*.rdc";
|
||||
this.saveDialog.Title = "Save Log As";
|
||||
//
|
||||
// toolStripSeparator13
|
||||
// startReplayLoopToolStripMenuItem
|
||||
//
|
||||
this.toolStripSeparator13.Name = "toolStripSeparator13";
|
||||
this.toolStripSeparator13.Size = new System.Drawing.Size(271, 6);
|
||||
//
|
||||
// startAndroidRemoteServerToolStripMenuItem
|
||||
//
|
||||
this.startAndroidRemoteServerToolStripMenuItem.Name = "startAndroidRemoteServerToolStripMenuItem";
|
||||
this.startAndroidRemoteServerToolStripMenuItem.Size = new System.Drawing.Size(274, 26);
|
||||
this.startAndroidRemoteServerToolStripMenuItem.Text = "Start Android Remote Server";
|
||||
this.startAndroidRemoteServerToolStripMenuItem.Click += new System.EventHandler(this.startAndroidRemoteServerToolStripMenuItem_Click);
|
||||
this.startReplayLoopToolStripMenuItem.Name = "startReplayLoopToolStripMenuItem";
|
||||
this.startReplayLoopToolStripMenuItem.Size = new System.Drawing.Size(213, 22);
|
||||
this.startReplayLoopToolStripMenuItem.Text = "Start Replay Loop";
|
||||
this.startReplayLoopToolStripMenuItem.Click += new System.EventHandler(this.startReplayLoopToolStripMenuItem_Click);
|
||||
//
|
||||
// MainWindow
|
||||
//
|
||||
@@ -931,5 +940,6 @@
|
||||
private System.Windows.Forms.ToolStripDropDownButton contextChooser;
|
||||
private System.Windows.Forms.ToolStripMenuItem localContext;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator13;
|
||||
private System.Windows.Forms.ToolStripMenuItem startReplayLoopToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
@@ -148,6 +148,7 @@ namespace renderdocui.Windows
|
||||
m_InitRemoteIdent = remoteIdent;
|
||||
OwnTemporaryLog = temp;
|
||||
|
||||
startReplayLoopToolStripMenuItem.Enabled = false;
|
||||
resolveSymbolsToolStripMenuItem.Enabled = false;
|
||||
resolveSymbolsToolStripMenuItem.Text = "Resolve Symbols";
|
||||
|
||||
@@ -277,6 +278,7 @@ namespace renderdocui.Windows
|
||||
statusIcon.Image = null;
|
||||
statusProgress.Visible = false;
|
||||
|
||||
startReplayLoopToolStripMenuItem.Enabled = false;
|
||||
resolveSymbolsToolStripMenuItem.Enabled = false;
|
||||
resolveSymbolsToolStripMenuItem.Text = "Resolve Symbols";
|
||||
|
||||
@@ -439,6 +441,8 @@ namespace renderdocui.Windows
|
||||
|
||||
statusProgress.Visible = false;
|
||||
|
||||
startReplayLoopToolStripMenuItem.Enabled = true;
|
||||
|
||||
m_Core.Renderer.BeginInvoke((ReplayRenderer r) => {
|
||||
bool hasResolver = r.HasCallstacks();
|
||||
|
||||
@@ -2033,5 +2037,69 @@ namespace renderdocui.Windows
|
||||
device = m_SelectedHost.Hostname;
|
||||
StaticExports.StartAndroidRemoteServer(device);
|
||||
}
|
||||
|
||||
private void startReplayLoopToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!m_Core.LogLoaded)
|
||||
return;
|
||||
|
||||
Form popup = new Form();
|
||||
popup.Icon = this.Icon;
|
||||
popup.StartPosition = FormStartPosition.CenterScreen;
|
||||
popup.FormBorderStyle = FormBorderStyle.SizableToolWindow;
|
||||
popup.SizeGripStyle = SizeGripStyle.Hide;
|
||||
|
||||
FetchTexture displayTex = null;
|
||||
|
||||
// display the texture bound at the last drawcall - typically the present
|
||||
var lastDraw = m_Core.CurDrawcalls[m_Core.CurDrawcalls.Length - 1];
|
||||
while (lastDraw.children != null && lastDraw.children.Length > 0)
|
||||
lastDraw = lastDraw.children[lastDraw.children.Length - 1];
|
||||
|
||||
displayTex = m_Core.GetTexture(lastDraw.copyDestination);
|
||||
if (displayTex == null)
|
||||
displayTex = m_Core.GetTexture(lastDraw.outputs[0]);
|
||||
|
||||
if (displayTex == null)
|
||||
{
|
||||
// if no texture was bound, then use the first colour swapbuffer
|
||||
foreach (FetchTexture tex in m_Core.CurTextures)
|
||||
{
|
||||
if (tex.creationFlags.HasFlag(TextureCreationFlags.SwapBuffer) &&
|
||||
tex.format.compType != FormatComponentType.Depth &&
|
||||
tex.format.specialFormat != SpecialFormat.D16S8 &&
|
||||
tex.format.specialFormat != SpecialFormat.D24S8 &&
|
||||
tex.format.specialFormat != SpecialFormat.D32S8)
|
||||
{
|
||||
displayTex = tex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResourceId id = ResourceId.Null;
|
||||
|
||||
if (displayTex != null)
|
||||
{
|
||||
id = displayTex.ID;
|
||||
popup.ClientSize = new Size((int)displayTex.width, (int)displayTex.height);
|
||||
popup.Text = "Looping replay of " + m_Core.LogFileName + " Displaying " + displayTex.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
popup.ClientSize = new Size(100, 100);
|
||||
popup.Text = "Looping replay of " + m_Core.LogFileName + " Displaying nothing";
|
||||
}
|
||||
|
||||
popup.CreateControl();
|
||||
|
||||
IntPtr handle = popup.Handle;
|
||||
|
||||
m_Core.Renderer.BeginInvoke((ReplayRenderer r) => { r.ReplayLoop(handle, id); });
|
||||
|
||||
popup.ShowDialog();
|
||||
|
||||
m_Core.Renderer.CancelReplayLoop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user