From d63e3b89ad0efe219254a2d6385087403ab6dced Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 4 Aug 2016 17:45:28 +0200 Subject: [PATCH] Add support for copying files back from remote server --- renderdoc/api/replay/renderdoc_replay.h | 14 ++-- renderdoc/core/remote_server.cpp | 74 ++++++++++++++++++---- renderdoccmd/renderdoccmd.cpp | 2 +- renderdocui/Code/RenderManager.cs | 53 +++++++++++++++- renderdocui/Interop/ReplayRenderer.cs | 17 ++++- renderdocui/Windows/Dialogs/LiveCapture.cs | 20 +++--- renderdocui/Windows/MainWindow.cs | 18 ++++-- 7 files changed, 162 insertions(+), 36 deletions(-) diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index d3e0a9d44..f137fc83e 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -487,7 +487,9 @@ struct IRemoteServer const CaptureOptions *opts) = 0; virtual void TakeOwnershipCapture(const char *filename) = 0; - virtual rdctype::str CopyCapture(const char *filename, float *progress) = 0; + virtual rdctype::str CopyCaptureToRemote(const char *filename, float *progress) = 0; + virtual void CopyCaptureFromRemote(const char *remotepath, const char *localpath, + float *progress) = 0; virtual ReplayCreateStatus OpenCapture(uint32_t proxyid, const char *logfile, float *progress, ReplayRenderer **rend) = 0; @@ -523,10 +525,12 @@ RemoteServer_ExecuteAndInject(RemoteServer *remote, const char *app, const char extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_TakeOwnershipCapture(RemoteServer *remote, const char *filename); -extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_CopyCapture(RemoteServer *remote, - const char *filename, - float *progress, - rdctype::str *remotepath); +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_CopyCaptureToRemote( + RemoteServer *remote, const char *filename, float *progress, rdctype::str *remotepath); +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_CopyCaptureFromRemote(RemoteServer *remote, + const char *remotepath, + const char *localpath, + float *progress); extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RemoteServer_OpenCapture(RemoteServer *remote, uint32_t proxyid, const char *logfile, diff --git a/renderdoc/core/remote_server.cpp b/renderdoc/core/remote_server.cpp index 1222aca12..3af8622ba 100644 --- a/renderdoc/core/remote_server.cpp +++ b/renderdoc/core/remote_server.cpp @@ -48,7 +48,8 @@ enum RemoteServerPacket eRemoteServer_Busy, eRemoteServer_RemoteDriverList, eRemoteServer_TakeOwnershipCapture, - eRemoteServer_CopyCapture, + eRemoteServer_CopyCaptureToRemote, + eRemoteServer_CopyCaptureFromRemote, eRemoteServer_OpenLog, eRemoteServer_LogOpenProgress, eRemoteServer_LogOpened, @@ -196,7 +197,21 @@ static void ActiveRemoteClientThread(void *data) sendSer.Serialise("", (*it).second); } } - else if(type == eRemoteServer_CopyCapture) + else if(type == eRemoteServer_CopyCaptureFromRemote) + { + string path; + recvser->Serialise("path", path); + + if(!SendChunkedFile(client, eRemoteServer_CopyCaptureFromRemote, path.c_str(), sendSer, NULL)) + { + RDCERR("Network error sending file"); + SAFE_DELETE(recvser); + break; + } + + sendSer.Rewind(); + } + else if(type == eRemoteServer_CopyCaptureToRemote) { string cap_file; string dummy, dummy2; @@ -213,6 +228,7 @@ static void ActiveRemoteClientThread(void *data) RDCERR("Network error receiving file"); SAFE_DELETE(fileRecv); + SAFE_DELETE(recvser); break; } @@ -222,7 +238,7 @@ static void ActiveRemoteClientThread(void *data) SAFE_DELETE(fileRecv); - sendType = eRemoteServer_CopyCapture; + sendType = eRemoteServer_CopyCaptureToRemote; sendSer.Serialise("path", cap_file); } else if(type == eRemoteServer_TakeOwnershipCapture) @@ -337,6 +353,8 @@ static void ActiveRemoteClientThread(void *data) { bool ok = proxy->Tick(type, recvser); + SAFE_DELETE(recvser); + if(!ok) break; @@ -345,7 +363,7 @@ static void ActiveRemoteClientThread(void *data) SAFE_DELETE(recvser); - if(type != eRemoteServer_Noop && !SendPacket(client, sendType, sendSer)) + if(sendType != eRemoteServer_Noop && !SendPacket(client, sendType, sendSer)) { RDCERR("Network error sending supported driver list"); break; @@ -683,10 +701,32 @@ public: return ident; } - rdctype::str CopyCapture(const char *filename, float *progress) + void CopyCaptureFromRemote(const char *remotepath, const char *localpath, float *progress) + { + string path = remotepath; + Serialiser sendData("", Serialiser::WRITING, false); + sendData.Serialise("path", path); + Send(eRemoteServer_CopyCaptureFromRemote, sendData); + + float dummy = 0.0f; + if(progress == NULL) + progress = &dummy; + + Serialiser *fileRecv = NULL; + + if(!RecvChunkedFile(m_Socket, eRemoteServer_CopyCaptureFromRemote, localpath, fileRecv, progress)) + { + SAFE_DELETE(fileRecv); + RDCERR("Network error receiving file"); + return; + } + SAFE_DELETE(fileRecv); + } + + rdctype::str CopyCaptureToRemote(const char *filename, float *progress) { Serialiser sendData("", Serialiser::WRITING, false); - Send(eRemoteServer_CopyCapture, sendData); + Send(eRemoteServer_CopyCaptureToRemote, sendData); float dummy = 0.0f; if(progress == NULL) @@ -694,7 +734,7 @@ public: sendData.Rewind(); - if(!SendChunkedFile(m_Socket, eRemoteServer_CopyCapture, filename, sendData, progress)) + if(!SendChunkedFile(m_Socket, eRemoteServer_CopyCaptureToRemote, filename, sendData, progress)) { SAFE_DELETE(m_Socket); return ""; @@ -704,7 +744,7 @@ public: Serialiser *ser = NULL; Get(type, &ser); - if(type == eRemoteServer_CopyCapture && ser) + if(type == eRemoteServer_CopyCaptureToRemote && ser) { string remotepath; ser->Serialise("path", remotepath); @@ -875,16 +915,24 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_TakeOwnershipCapture(Rem remote->TakeOwnershipCapture(filename); } -extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_CopyCapture(RemoteServer *remote, - const char *filename, - float *progress, - rdctype::str *remotepath) +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_CopyCaptureToRemote(RemoteServer *remote, + const char *filename, + float *progress, + rdctype::str *remotepath) { - rdctype::str path = remote->CopyCapture(filename, progress); + rdctype::str path = remote->CopyCaptureToRemote(filename, progress); if(remotepath) *remotepath = path; } +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_CopyCaptureFromRemote(RemoteServer *remote, + const char *remotepath, + const char *localpath, + float *progress) +{ + remote->CopyCaptureFromRemote(remotepath, localpath, progress); +} + extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RemoteServer_OpenCapture(RemoteServer *remote, uint32_t proxyid, const char *logfile, float *progress, ReplayRenderer **rend) diff --git a/renderdoccmd/renderdoccmd.cpp b/renderdoccmd/renderdoccmd.cpp index 055eb1e5c..7e016cffe 100644 --- a/renderdoccmd/renderdoccmd.cpp +++ b/renderdoccmd/renderdoccmd.cpp @@ -477,7 +477,7 @@ struct ReplayCommand : public Command std::cerr << "Copying capture file to remote server" << std::endl; float progress = 0.0f; - rdctype::str remotePath = remote->CopyCapture(filename.c_str(), &progress); + rdctype::str remotePath = remote->CopyCaptureToRemote(filename.c_str(), &progress); ReplayRenderer *renderer = NULL; status = remote->OpenCapture(~0U, remotePath.elems, &progress, &renderer); diff --git a/renderdocui/Code/RenderManager.cs b/renderdocui/Code/RenderManager.cs index 0cb17e1e5..b84328840 100644 --- a/renderdocui/Code/RenderManager.cs +++ b/renderdocui/Code/RenderManager.cs @@ -118,7 +118,13 @@ namespace renderdocui.Code if (local) { - System.IO.File.Delete(logfile); + try + { + System.IO.File.Delete(logfile); + } + catch (Exception) + { + } } else { @@ -129,6 +135,51 @@ namespace renderdocui.Code } } + public void CopyCaptureFromRemote(string remotepath, string localpath, Form window) + { + if (m_Remote != null) + { + bool copied = false; + float progress = 0.0f; + + renderdocui.Windows.ProgressPopup modal = + new renderdocui.Windows.ProgressPopup( + (renderdocui.Windows.ModalCloseCallback)(() => { return copied; }), + true); + modal.SetModalText("Transferring..."); + + Thread progressThread = Helpers.NewThread(new ThreadStart(() => + { + modal.LogfileProgressBegin(); + + while (!copied) + { + Thread.Sleep(2); + + modal.LogfileProgress(progress); + } + })); + progressThread.Start(); + + BeginInvoke((ReplayRenderer r) => + { + m_Remote.CopyCaptureFromRemote(remotepath, localpath, ref progress); + + copied = true; + }); + + modal.ShowDialog(window); + + // if the copy didn't succeed, throw + if (!System.IO.File.Exists(localpath)) + throw new System.IO.FileNotFoundException("File couldn't be transferred from remote host", remotepath); + } + else + { + System.IO.File.Copy(remotepath, localpath, true); + } + } + public bool Running { get { return m_Running; } diff --git a/renderdocui/Interop/ReplayRenderer.cs b/renderdocui/Interop/ReplayRenderer.cs index 8c5154123..58dc2d25b 100644 --- a/renderdocui/Interop/ReplayRenderer.cs +++ b/renderdocui/Interop/ReplayRenderer.cs @@ -864,7 +864,9 @@ namespace renderdoc [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern void RemoteServer_TakeOwnershipCapture(IntPtr real, IntPtr filename); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern void RemoteServer_CopyCapture(IntPtr real, IntPtr filename, ref float progress, IntPtr remotepath); + private static extern void RemoteServer_CopyCaptureToRemote(IntPtr real, IntPtr filename, ref float progress, IntPtr remotepath); + [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void RemoteServer_CopyCaptureFromRemote(IntPtr real, IntPtr remotepath, IntPtr localpath, ref float progress); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern ReplayCreateStatus RemoteServer_OpenCapture(IntPtr real, UInt32 proxyid, IntPtr logfile, ref float progress, ref IntPtr rendPtr); @@ -954,7 +956,7 @@ namespace renderdoc IntPtr filename_mem = CustomMarshal.MakeUTF8String(filename); - RemoteServer_CopyCapture(m_Real, filename_mem, ref progress, remotepath); + RemoteServer_CopyCaptureToRemote(m_Real, filename_mem, ref progress, remotepath); CustomMarshal.Free(filename_mem); @@ -965,6 +967,17 @@ namespace renderdoc return remote; } + public void CopyCaptureFromRemote(string remotepath, string localpath, ref float progress) + { + IntPtr remotepath_mem = CustomMarshal.MakeUTF8String(remotepath); + IntPtr localpath_mem = CustomMarshal.MakeUTF8String(localpath); + + RemoteServer_CopyCaptureFromRemote(m_Real, remotepath_mem, localpath_mem, ref progress); + + CustomMarshal.Free(remotepath_mem); + CustomMarshal.Free(localpath_mem); + } + public ReplayRenderer OpenCapture(int proxyid, string logfile, ref float progress) { IntPtr rendPtr = IntPtr.Zero; diff --git a/renderdocui/Windows/Dialogs/LiveCapture.cs b/renderdocui/Windows/Dialogs/LiveCapture.cs index 14c5aaa3a..397a0257f 100644 --- a/renderdocui/Windows/Dialogs/LiveCapture.cs +++ b/renderdocui/Windows/Dialogs/LiveCapture.cs @@ -364,18 +364,20 @@ namespace renderdocui.Windows // This ensures that if the user deletes the saved path we can still open or re-save it. if (path.Length > 0) { - string localpath = log.path; - - if (!log.local) - { - // copy locally first - } - try { - File.Copy(localpath, path, true); + if (log.local) + { + File.Copy(log.path, path, true); + } + else + { + m_Core.Renderer.CopyCaptureFromRemote(log.path, path, this); + m_Core.Renderer.DeleteCapture(log.path, false); + } + log.saved = true; - log.path = localpath; + log.path = path; m_Core.Config.AddRecentFile(m_Core.Config.RecentLogFiles, path, 10); m_Main.PopulateRecentFiles(); } diff --git a/renderdocui/Windows/MainWindow.cs b/renderdocui/Windows/MainWindow.cs index cab00a698..bf162463c 100644 --- a/renderdocui/Windows/MainWindow.cs +++ b/renderdocui/Windows/MainWindow.cs @@ -246,7 +246,7 @@ namespace renderdocui.Windows { statusProgress.Visible = false; statusText.Text = ""; - statusIcon.Image = global::renderdocui.Properties.Resources.hourglass; + statusIcon.Image = null; } else { @@ -1317,7 +1317,7 @@ namespace renderdocui.Windows if (res == DialogResult.OK) { - if (!File.Exists(m_Core.LogFileName)) + if (m_Core.IsLogLocal && !File.Exists(m_Core.LogFileName)) { MessageBox.Show("Logfile " + m_Core.LogFileName + " couldn't be found, cannot save.", "File not found", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -1326,9 +1326,17 @@ namespace renderdocui.Windows try { - // we copy the (possibly) temp log to the desired path, but the log item remains referring to the original path. - // This ensures that if the user deletes the saved path we can still open or re-save it. - File.Copy(m_Core.LogFileName, saveDialog.FileName, true); + if (m_Core.IsLogLocal) + { + // we copy the (possibly) temp log to the desired path, but the log item remains referring to the original path. + // This ensures that if the user deletes the saved path we can still open or re-save it. + File.Copy(m_Core.LogFileName, saveDialog.FileName, true); + } + else + { + m_Core.Renderer.CopyCaptureFromRemote(m_Core.LogFileName, saveDialog.FileName, this); + } + m_Core.Config.AddRecentFile(m_Core.Config.RecentLogFiles, saveDialog.FileName, 10); PopulateRecentFiles(); SetTitle(saveDialog.FileName);