From 7a2305ae3148f8f3287a272e7228299f4dae4e47 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 1 Jan 2018 14:56:10 +0000 Subject: [PATCH] Change by-ref passed float or bool parameters to callbacks in public API * Mostly used for passing a progress float back during a long blocking call like opening a capture or doing a copy. * This is much more feasible for python to bind to. * In several cases we just use a tiny lambda that updates a float anyway since we can't push the progress directly into a progress dialog, but need to let it query from a temporary in-between float. --- qrenderdoc/Code/CaptureContext.cpp | 4 +- qrenderdoc/Code/ReplayManager.cpp | 13 +-- qrenderdoc/Code/ReplayManager.h | 4 +- qrenderdoc/Windows/Dialogs/CaptureDialog.cpp | 3 +- qrenderdoc/Windows/MainWindow.cpp | 3 +- renderdoc/api/replay/renderdoc_replay.h | 81 ++++++++++++------- renderdoc/core/android.cpp | 31 +++---- renderdoc/core/core.h | 19 ++--- renderdoc/core/remote_server.cpp | 65 ++++++++------- renderdoc/core/target_control.cpp | 5 +- renderdoc/os/os_specific.h | 2 +- .../os/posix/android/android_callstack.cpp | 2 +- renderdoc/os/posix/apple/apple_callstack.cpp | 2 +- renderdoc/os/posix/linux/linux_callstack.cpp | 6 +- renderdoc/os/win32/win32_callstack.cpp | 11 +-- renderdoc/replay/capture_file.cpp | 22 ++--- renderdoc/replay/entry_points.cpp | 16 ++-- .../serialise/codecs/chrome_json_codec.cpp | 13 ++- renderdoc/serialise/codecs/xml_codec.cpp | 28 ++++--- renderdoc/serialise/serialiser.cpp | 8 +- renderdoc/serialise/serialiser.h | 14 ++-- renderdoc/serialise/streamio.cpp | 9 ++- renderdoc/serialise/streamio.h | 2 +- renderdoccmd/renderdoccmd.cpp | 3 +- 24 files changed, 212 insertions(+), 154 deletions(-) diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index 4827a2877..2eed4f7a1 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -214,7 +214,7 @@ void CaptureContext::LoadCaptureThreaded(const QString &captureFile, const QStri m_PostloadProgress = 0.0f; // this function call will block until the capture is either loaded, or there's some failure - m_Renderer.OpenCapture(captureFile, &m_LoadProgress); + m_Renderer.OpenCapture(captureFile, [this](float p) { m_LoadProgress = p; }); // if the renderer isn't running, we hit a failure case so display an error message if(!m_Renderer.IsRunning()) @@ -670,7 +670,7 @@ void CaptureContext::RecompressCapture() float progress = 0.0f; LambdaThread *th = new LambdaThread([this, cap, destFilename, &progress]() { - cap->Convert(destFilename.toUtf8().data(), "rdc", &progress); + cap->Convert(destFilename.toUtf8().data(), "rdc", [&progress](float p) { progress = p; }); }); th->start(); // wait a few ms before popping up a progress bar diff --git a/qrenderdoc/Code/ReplayManager.cpp b/qrenderdoc/Code/ReplayManager.cpp index 2c57da2f2..85c1583c4 100644 --- a/qrenderdoc/Code/ReplayManager.cpp +++ b/qrenderdoc/Code/ReplayManager.cpp @@ -42,7 +42,7 @@ ReplayManager::~ReplayManager() RENDERDOC_UnregisterMemoryRegion(this); } -void ReplayManager::OpenCapture(const QString &capturefile, float *progress) +void ReplayManager::OpenCapture(const QString &capturefile, RENDERDOC_ProgressCallback progress) { if(m_Running) return; @@ -50,8 +50,6 @@ void ReplayManager::OpenCapture(const QString &capturefile, float *progress) // TODO maybe we could expose this choice to the user? int proxyRenderer = -1; - *progress = 0.0f; - m_Thread = new LambdaThread([this, proxyRenderer, capturefile, progress]() { run(proxyRenderer, capturefile, progress); }); @@ -171,7 +169,8 @@ rdcstr ReplayManager::CopyCaptureToRemote(const rdcstr &localpath, QWidget *wind auto lambda = [this, localpath, &remotepath, &progress, &copied](IReplayController *r) { QMutexLocker autolock(&m_RemoteLock); - remotepath = m_Remote->CopyCaptureToRemote(localpath.c_str(), &progress); + remotepath = + m_Remote->CopyCaptureToRemote(localpath.c_str(), [&progress](float p) { progress = p; }); copied = true; }; @@ -204,7 +203,8 @@ void ReplayManager::CopyCaptureFromRemote(const rdcstr &remotepath, const rdcstr auto lambda = [this, localpath, remotepath, &progress, &copied](IReplayController *r) { QMutexLocker autolock(&m_RemoteLock); - m_Remote->CopyCaptureFromRemote(remotepath.c_str(), localpath.c_str(), &progress); + m_Remote->CopyCaptureFromRemote(remotepath.c_str(), localpath.c_str(), + [&progress](float p) { progress = p; }); copied = true; }; @@ -408,7 +408,8 @@ void ReplayManager::PushInvoke(ReplayManager::InvokeHandle *cmd) m_RenderCondition.wakeAll(); } -void ReplayManager::run(int proxyRenderer, const QString &capturefile, float *progress) +void ReplayManager::run(int proxyRenderer, const QString &capturefile, + RENDERDOC_ProgressCallback progress) { m_Renderer = NULL; diff --git a/qrenderdoc/Code/ReplayManager.h b/qrenderdoc/Code/ReplayManager.h index 9bdcbcb1f..7565d924b 100644 --- a/qrenderdoc/Code/ReplayManager.h +++ b/qrenderdoc/Code/ReplayManager.h @@ -47,7 +47,7 @@ public: ReplayManager(); ~ReplayManager(); - void OpenCapture(const QString &capturefile, float *progress); + void OpenCapture(const QString &capturefile, RENDERDOC_ProgressCallback progress); void DeleteCapture(const rdcstr &capturefile, bool local); bool IsRunning(); @@ -111,7 +111,7 @@ private: bool selfdelete; }; - void run(int proxyRenderer, const QString &capturefile, float *progress); + void run(int proxyRenderer, const QString &capturefile, RENDERDOC_ProgressCallback progress); QMutex m_RenderLock; QQueue m_RenderQueue; diff --git a/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp b/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp index 720a5b9dc..b5ee25010 100644 --- a/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp +++ b/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp @@ -610,7 +610,8 @@ void CaptureDialog::androidWarn_mouseClick() // call into APK pull, patch, install routine, then continue LambdaThread *patch = new LambdaThread([this, exe, &patchSucceeded, &progress]() { rdcstr host = m_Ctx.Replay().CurrentRemote()->hostname; - if(RENDERDOC_AddLayerToAndroidPackage(host.c_str(), exe.toUtf8().data(), &progress)) + if(RENDERDOC_AddLayerToAndroidPackage(host.c_str(), exe.toUtf8().data(), + [&progress](float p) { progress = p; })) { // Sucess! patchSucceeded = true; diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 4d2cd1fc9..336c905c5 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -2012,7 +2012,8 @@ void MainWindow::on_action_Resolve_Symbols_triggered() bool finished = false; m_Ctx.Replay().AsyncInvoke([this, &progress, &finished](IReplayController *) { - bool success = m_Ctx.Replay().GetCaptureAccess()->InitResolver(&progress); + bool success = + m_Ctx.Replay().GetCaptureAccess()->InitResolver([&progress](float p) { progress = p; }); if(!success) { diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 139dab9c3..eec728df9 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -27,6 +27,7 @@ #include #include +#include // Guidelines for documentation: // @@ -483,12 +484,37 @@ DECLARE_REFLECTION_STRUCT(ResourceId); #include "shader_types.h" #include "vk_pipestate.h" +// there's not a good way to document a callback, so for lack of a better place we declare these +// here and document them immediately below. They can be linked to from anywhere by name. +typedef std::function RENDERDOC_KillCallback; +typedef std::function RENDERDOC_ProgressCallback; + DOCUMENT(R"(A stateful output handle that contains the current configuration for one particular view of the capture. This allows multiple outputs to run independently without interfering with each other. The different types are enumerated in :class:`ReplayOutputType`. +.. function:: KillCallback() + + Not an actual member function - the signature for any ``KillCallback`` callbacks. + + Called whenever some on-going blocking process needs to determine if it should close. + + :return: Whether or not the process should be killed. + :rtype: ``bool`` + +.. function:: ProgressCallback() + + Not an actual member function - the signature for any ``ProgressCallback`` callbacks. + + Called by an on-going blocking process to update a progress bar or similar user feedback. + + The progress value will go from 0.0 to 1.0 as the process completes. Any other value will indicate + that the process has completed + + :param float progress: The latest progress amount. + .. data:: NoResult No result was found in e.g. :meth:`PickVertex`. @@ -1240,12 +1266,12 @@ necessary. This function blocks while trying to initialise callstack resolving, so it should be called on a separate thread. -:param float progress: A reference to a ``float`` value that will be updated as the init happens - from ``0.0`` to ``1.0``. The parameter can be ``None`` if no progress update is desired. +:param ProgressCallback progress: A callback that will be repeatedly called with an updated progress + value for the resolver process. Can be ``None`` if no progress is desired. :return: ``True`` if the resolver successfully initialised, ``False`` if something went wrong. :rtype: ``bool`` )"); - virtual bool InitResolver(float *progress) = 0; + virtual bool InitResolver(RENDERDOC_ProgressCallback progress) = 0; DOCUMENT(R"(Retrieve the details of each stackframe in the provided callstack. @@ -1362,12 +1388,12 @@ This is primarily useful for when a capture is only stored locally and must be r the capture must be available on the machine where the replay happens. :param str filename: The path to the file on the local system. -:param float progress: A reference to a float value that will be updated as the copy happens from - ``0.0`` to ``1.0``. The parameter can be ``None`` if no progress update is desired. +:param ProgressCallback progress: A callback that will be repeatedly called with an updated progress + value for the copy. Can be ``None`` if no progress is desired. :return: The path on the remote system where the capture was saved temporarily. :rtype: ``str`` )"); - virtual rdcstr CopyCaptureToRemote(const char *filename, float *progress) = 0; + virtual rdcstr CopyCaptureToRemote(const char *filename, RENDERDOC_ProgressCallback progress) = 0; DOCUMENT(R"(Copy a capture file that is stored on the remote system to the local system. @@ -1375,11 +1401,11 @@ This function will block until the copy is fully complete, or an error has occur :param str remotepath: The remote path where the file should be copied from. :param str localpath: The local path where the file should be saved. -:param float progress: A reference to a ``float`` value that will be updated as the copy happens - from ``0.0`` to ``1.0``. The parameter can be ``None`` if no progress update is desired. +:param ProgressCallback progress: A callback that will be repeatedly called with an updated progress + value for the copy. Can be ``None`` if no progress is desired. )"); virtual void CopyCaptureFromRemote(const char *remotepath, const char *localpath, - float *progress) = 0; + RENDERDOC_ProgressCallback progress) = 0; DOCUMENT(R"(Open a capture file for remote capture and replay. The capture will be opened and replayed on the remote system, and proxied to the local system with a given renderer. As much work @@ -1396,15 +1422,14 @@ or an error has occurred. or :data:`NoPreference` to indicate no preference for any proxy. :param str logfile: The path on the remote system where the file is. If the file is only available locally you can use :meth:`CopyCaptureToRemote` to transfer it over the remote connection. -:param float progress: A reference to a ``float`` value that will be updated as the copy happens - from ``0.0`` to ``1.0``. The parameter can be ``None`` if no progress update is desired. +:param ProgressCallback progress: A callback that will be repeatedly called with an updated progress + value for the opening. Can be ``None`` if no progress is desired. :return: A tuple containing the status of opening the capture, whether success or failure, and the resulting :class:`ReplayController` handle if successful. :rtype: ``tuple`` of :class:`ReplayStatus` and :class:`ReplayController` )"); - virtual rdcpair OpenCapture(uint32_t proxyid, - const char *logfile, - float *progress) = 0; + virtual rdcpair OpenCapture( + uint32_t proxyid, const char *logfile, RENDERDOC_ProgressCallback progress) = 0; DOCUMENT(R"(Close a capture analysis handle previously opened by :meth:`OpenCapture`. @@ -1477,11 +1502,13 @@ representation back to native RDC. :param str filename: The filename to save to. :param str filetype: The format to convert to. -:param float progress: A reference to a ``float`` value that will be updated as the copy happens +:param ProgressCallback progress: A callback that will be repeatedly called with an updated progress + value for the conversion. Can be ``None`` if no progress is desired. :return: The status of the conversion operation, whether it succeeded or failed (and how it failed). :rtype: ReplayStatus )"); - virtual ReplayStatus Convert(const char *filename, const char *filetype, float *progress) = 0; + virtual ReplayStatus Convert(const char *filename, const char *filetype, + RENDERDOC_ProgressCallback progress) = 0; DOCUMENT(R"(Returns the human-readable error string for the last error received. @@ -1556,13 +1583,13 @@ This function will block until the capture is fully loaded and ready. Once the replay is created, this :class:`CaptureFile` can be shut down, there is no dependency on it by the :class:`ReplayController`. -:param float progress: A reference to a ``float`` value that will be updated as the copy happens - from ``0.0`` to ``1.0``. The parameter can be ``None`` if no progress update is desired. +:param ProgressCallback progress: A callback that will be repeatedly called with an updated progress + value for the opening. Can be ``None`` if no progress is desired. :return: A tuple containing the status of opening the capture, whether success or failure, and the resulting :class:`ReplayController` handle if successful. :rtype: ``tuple`` of :class:`ReplayStatus` and :class:`ReplayController`. )"); - virtual rdcpair OpenCapture(float *progress) = 0; + virtual rdcpair OpenCapture(RENDERDOC_ProgressCallback progress) = 0; DOCUMENT(R"(Returns the structured data for this capture. @@ -1825,16 +1852,15 @@ DOCUMENT(R"(This launches a remote server which will continually run in a loop t from external sources. This function will block until a remote connection tells the server to shut down, or the -``killReplay`` value becomes ``True``. +``killReplay`` callback returns ``True``. :param str host: The name of the interface to listen on. :param int port: The port to listen on, or the default port if 0. -:param bool killReplay: A reference to a ``bool`` that can be set to ``True`` to shut down the - server. +:param KillCallback killReplay: A callback that returns a ``bool`` indicating if the server should + be shut down or not. )"); -extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_BecomeRemoteServer(const char *listenhost, - uint32_t port, - volatile bool *killReplay); +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_BecomeRemoteServer( + const char *listenhost, uint32_t port, RENDERDOC_KillCallback killReplay); ////////////////////////////////////////////////////////////////////////// // Injection/execution capture functions. @@ -2035,9 +2061,8 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_PushLayerToInstalledAndroid const char *exe); DOCUMENT("Internal function that attempts to modify APK contents, adding Vulkan layer."); -extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage(const char *host, - const char *exe, - float *progress); +extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage( + const char *host, const char *exe, RENDERDOC_ProgressCallback progress); DOCUMENT("Internal function that runs unit tests."); extern "C" RENDERDOC_API int RENDERDOC_CC RENDERDOC_RunUnitTests(const rdcstr &command, diff --git a/renderdoc/core/android.cpp b/renderdoc/core/android.cpp index 7b5a3d39c..a7fb6cde5 100644 --- a/renderdoc/core/android.cpp +++ b/renderdoc/core/android.cpp @@ -1341,9 +1341,8 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_PushLayerToInstalledAndroid return SearchForAndroidLayer(deviceID, layerDst, layerName, foundLayer); } -extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage(const char *host, - const char *exe, - float *progress) +extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage( + const char *host, const char *exe, RENDERDOC_ProgressCallback progress) { Process::ProcessResult result = {}; string packageName(basename(string(exe))); @@ -1352,12 +1351,16 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage(co std::string deviceID; Android::extractDeviceIDAndIndex(host, index, deviceID); - *progress = 0.0f; + // make sure progress is valid so we don't have to check it everywhere + if(!progress) + progress = [](float) {}; + + progress(0.0f); if(!CheckPatchingRequirements()) return false; - *progress = 0.11f; + progress(0.11f); // Detect which ABI was installed on the device string abi = DetermineInstalledABI(deviceID, packageName); @@ -1376,48 +1379,48 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC RENDERDOC_AddLayerToAndroidPackage(co string origAPK(tmpDir + packageName + ".orig.apk"); string alignedAPK(origAPK + ".aligned.apk"); - *progress = 0.21f; + progress(0.21f); // Try the following steps, bailing if anything fails if(!PullAPK(deviceID, pkgPath, origAPK)) return false; - *progress = 0.31f; + progress(0.31f); if(!CheckAPKPermissions(origAPK)) return false; - *progress = 0.41f; + progress(0.41f); if(!RemoveAPKSignature(origAPK)) return false; - *progress = 0.51f; + progress(0.51f); if(!AddLayerToAPK(origAPK, layerPath, layerName, abi, tmpDir)) return false; - *progress = 0.61f; + progress(0.61f); if(!RealignAPK(origAPK, alignedAPK, tmpDir)) return false; - *progress = 0.71f; + progress(0.71f); if(!DebugSignAPK(alignedAPK, tmpDir)) return false; - *progress = 0.81f; + progress(0.81f); if(!UninstallOriginalAPK(deviceID, packageName, tmpDir)) return false; - *progress = 0.91f; + progress(0.91f); if(!ReinstallPatchedAPK(deviceID, alignedAPK, abi, packageName, tmpDir)) return false; - *progress = 1.0f; + progress(1.0f); // All clean! return true; diff --git a/renderdoc/core/core.h b/renderdoc/core/core.h index 0b76618f9..4ba37eb4f 100644 --- a/renderdoc/core/core.h +++ b/renderdoc/core/core.h @@ -320,9 +320,10 @@ typedef ReplayStatus (*ReplayDriverProvider)(RDCFile *rdc, IReplayDriver **drive typedef void (*StructuredProcessor)(RDCFile *rdc, SDFile &structData); typedef ReplayStatus (*CaptureImporter)(const char *filename, StreamReader &reader, RDCFile *rdc, - SDFile &structData, float *progress); + SDFile &structData, RENDERDOC_ProgressCallback progress); typedef ReplayStatus (*CaptureExporter)(const char *filename, const RDCFile &rdc, - const SDFile &structData, float *progress); + const SDFile &structData, + RENDERDOC_ProgressCallback progress); typedef bool (*VulkanLayerCheck)(VulkanLayerFlags &flags, std::vector &myJSONs, std::vector &otherJSONs); @@ -340,16 +341,16 @@ public: static RenderDoc &Inst(); template - void SetProgressPointer(float *progress) + void SetProgressCallback(RENDERDOC_ProgressCallback progress) { - m_ProgressPointers[TypeName()] = progress; + m_ProgressCallbacks[TypeName()] = progress; } template void SetProgress(ProgressType section, float delta) { - float *ptr = m_ProgressPointers[TypeName()]; - if(ptr == NULL || section < ProgressType::First || section >= ProgressType::Count) + RENDERDOC_ProgressCallback cb = m_ProgressCallbacks[TypeName()]; + if(!cb || section < ProgressType::First || section >= ProgressType::Count) return; float progress = 0.0f; @@ -367,7 +368,7 @@ public: if(progress >= 0.9999f) progress = 1.0f; - *ptr = progress; + cb(progress); } // set from outside of the device creation interface @@ -386,7 +387,7 @@ public: bool IsReplayApp() const { return m_Replay; } const string &GetConfigSetting(string name) { return m_ConfigSettings[name]; } void SetConfigSetting(string name, string value) { m_ConfigSettings[name] = value; } - void BecomeRemoteServer(const char *listenhost, uint16_t port, volatile bool &killReplay); + void BecomeRemoteServer(const char *listenhost, uint16_t port, RENDERDOC_KillCallback killReplay); void SetCaptureOptions(const CaptureOptions &opts); const CaptureOptions &GetCaptureOptions() const { return m_Options; } @@ -567,7 +568,7 @@ private: Threading::CriticalSection m_DriverLock; std::map m_ActiveDrivers; - std::map m_ProgressPointers; + std::map m_ProgressCallbacks; Threading::CriticalSection m_CaptureLock; vector m_Captures; diff --git a/renderdoc/core/remote_server.cpp b/renderdoc/core/remote_server.cpp index c815c369b..cfc1ca93b 100644 --- a/renderdoc/core/remote_server.cpp +++ b/renderdoc/core/remote_server.cpp @@ -406,7 +406,7 @@ static void ActiveRemoteClientThread(ClientThread *threadData) bool kill = false; float progress = 0.0f; - RenderDoc::Inst().SetProgressPointer(&progress); + RenderDoc::Inst().SetProgressCallback([&progress](float p) { progress = p; }); Threading::ThreadHandle ticker = Threading::CreateThread([&writer, &kill, &progress]() { while(!kill) @@ -439,7 +439,7 @@ static void ActiveRemoteClientThread(ClientThread *threadData) } else { - RenderDoc::Inst().SetProgressPointer(NULL); + RenderDoc::Inst().SetProgressCallback(RENDERDOC_ProgressCallback()); kill = true; Threading::JoinThread(ticker); @@ -510,7 +510,8 @@ static void ActiveRemoteClientThread(ClientThread *threadData) } }); - resolver = Callstack::MakeResolver(buf.data(), buf.size(), &progress); + resolver = Callstack::MakeResolver(buf.data(), buf.size(), + [&progress](float p) { progress = p; }); Threading::JoinThread(ticker); Threading::CloseThread(ticker); @@ -764,7 +765,8 @@ static void ActiveRemoteClientThread(ClientThread *threadData) SAFE_DELETE(client); } -void RenderDoc::BecomeRemoteServer(const char *listenhost, uint16_t port, volatile bool &killReplay) +void RenderDoc::BecomeRemoteServer(const char *listenhost, uint16_t port, + RENDERDOC_KillCallback killReplay) { Network::Socket *sock = Network::CreateServerSocket(listenhost, port, 1); @@ -855,7 +857,7 @@ void RenderDoc::BecomeRemoteServer(const char *listenhost, uint16_t port, volati std::vector inactives; - while(!killReplay) + while(!killReplay()) { Network::Socket *client = sock->AcceptClient(false); @@ -1230,7 +1232,8 @@ public: return ident; } - void CopyCaptureFromRemote(const char *remotepath, const char *localpath, float *progress) + void CopyCaptureFromRemote(const char *remotepath, const char *localpath, + RENDERDOC_ProgressCallback progress) { std::string path = remotepath; @@ -1240,10 +1243,6 @@ public: SERIALISE_ELEMENT(path); } - float dummy = 0.0f; - if(progress == NULL) - progress = &dummy; - { READ_DATA_SCOPE(); RemoteServerPacket type = ser.ReadChunk(); @@ -1252,7 +1251,7 @@ public: { StreamWriter streamWriter(FileIO::fopen(localpath, "wb"), Ownership::Stream); - ser.SerialiseStream(localpath, streamWriter, NULL); + ser.SerialiseStream(localpath, streamWriter, progress); if(ser.IsErrored()) { @@ -1269,14 +1268,14 @@ public: } } - rdcstr CopyCaptureToRemote(const char *filename, float *progress) + rdcstr CopyCaptureToRemote(const char *filename, RENDERDOC_ProgressCallback progress) { { WRITE_DATA_SCOPE(); SCOPED_SERIALISE_CHUNK(eRemoteServer_CopyCaptureToRemote); StreamReader fileStream(FileIO::fopen(filename, "rb")); - ser.SerialiseStream(filename, fileStream); + ser.SerialiseStream(filename, fileStream, progress); } std::string path; @@ -1312,7 +1311,7 @@ public: } rdcpair OpenCapture(uint32_t proxyid, const char *filename, - float *progressPtr) + RENDERDOC_ProgressCallback progress) { rdcpair ret; ret.first = ReplayStatus::InternalError; @@ -1325,12 +1324,6 @@ public: return ret; } - float dummy = 0.0f; - if(progressPtr == NULL) - progressPtr = &dummy; - - float &progress = *progressPtr; - // if the proxy id is ~0U, then we just don't care so let RenderDoc pick the most // appropriate supported proxy for the current platform. RDCDriver proxydrivertype = proxyid == ~0U ? RDCDriver::Unknown : m_Proxies[proxyid].first; @@ -1350,11 +1343,16 @@ public: if(reader.IsErrored() || type != eRemoteServer_LogOpenProgress) break; - SERIALISE_ELEMENT(progress); + float progressValue = 0.0f; + + SERIALISE_ELEMENT(progressValue); ser.EndChunk(); - RDCLOG("% 3.0f%%...", progress * 100.0f); + if(progress) + progress(progressValue); + + RDCLOG("% 3.0f%%...", progressValue * 100.0f); } if(reader.IsErrored() || type != eRemoteServer_LogOpened) @@ -1370,7 +1368,8 @@ public: ser.EndChunk(); } - progress = 1.0f; + if(progress) + progress(1.0f); if(status != ReplayStatus::Succeeded) { @@ -1624,14 +1623,8 @@ public: return hasCallstacks; } - bool InitResolver(float *progressPtr) + bool InitResolver(RENDERDOC_ProgressCallback progress) { - float dummy = 0.0f; - if(progressPtr == NULL) - progressPtr = &dummy; - - float &progress = *progressPtr; - { WRITE_DATA_SCOPE(); SCOPED_SERIALISE_CHUNK(eRemoteServer_InitResolver); @@ -1646,11 +1639,16 @@ public: if(reader.IsErrored() || type != eRemoteServer_ResolverProgress) break; - SERIALISE_ELEMENT(progress); + float progressValue = 0.0f; + + SERIALISE_ELEMENT(progressValue); ser.EndChunk(); - RDCLOG("% 3.0f%%...", progress * 100.0f); + if(progress) + progress(progressValue); + + RDCLOG("% 3.0f%%...", progressValue * 100.0f); } if(reader.IsErrored() || type != eRemoteServer_InitResolver) @@ -1665,7 +1663,8 @@ public: ser.EndChunk(); } - progress = 1.0f; + if(progress) + progress(1.0f); return success; } diff --git a/renderdoc/core/target_control.cpp b/renderdoc/core/target_control.cpp index 07ebd7f61..b5fcdaa79 100644 --- a/renderdoc/core/target_control.cpp +++ b/renderdoc/core/target_control.cpp @@ -106,7 +106,8 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli } float captureProgress = -1.0f; - RenderDoc::Inst().SetProgressPointer(&captureProgress); + RenderDoc::Inst().SetProgressCallback( + [&captureProgress](float p) { captureProgress = p; }); const int pingtime = 1000; // ping every 1000ms const int ticktime = 10; // tick every 10ms @@ -310,7 +311,7 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli } } - RenderDoc::Inst().SetProgressPointer(NULL); + RenderDoc::Inst().SetProgressCallback(RENDERDOC_ProgressCallback()); // give up our connection { diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h index 9529a431c..c9d0dae03 100644 --- a/renderdoc/os/os_specific.h +++ b/renderdoc/os/os_specific.h @@ -232,7 +232,7 @@ void Init(); Stackwalk *Collect(); Stackwalk *Create(); -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, float *progress); +StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback); bool GetLoadedModules(byte *buf, size_t &size); }; // namespace Callstack diff --git a/renderdoc/os/posix/android/android_callstack.cpp b/renderdoc/os/posix/android/android_callstack.cpp index 12a9a934c..f5212ef8a 100644 --- a/renderdoc/os/posix/android/android_callstack.cpp +++ b/renderdoc/os/posix/android/android_callstack.cpp @@ -76,7 +76,7 @@ bool GetLoadedModules(byte *buf, size_t &size) return true; } -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, float *progress) +StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) { RDCERR("Callstack resolving not supported on Android."); return NULL; diff --git a/renderdoc/os/posix/apple/apple_callstack.cpp b/renderdoc/os/posix/apple/apple_callstack.cpp index 4aa9ff1e0..70992b129 100644 --- a/renderdoc/os/posix/apple/apple_callstack.cpp +++ b/renderdoc/os/posix/apple/apple_callstack.cpp @@ -76,7 +76,7 @@ bool GetLoadedModules(byte *buf, size_t &size) return true; } -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, float *progress) +StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) { RDCERR("Callstack resolving not supported on Apple."); return NULL; diff --git a/renderdoc/os/posix/linux/linux_callstack.cpp b/renderdoc/os/posix/linux/linux_callstack.cpp index 651cf955c..63fc41294 100644 --- a/renderdoc/os/posix/linux/linux_callstack.cpp +++ b/renderdoc/os/posix/linux/linux_callstack.cpp @@ -221,7 +221,7 @@ private: std::map m_Cache; }; -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, float *progress) +StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) { // we look in the original locations for the files, we don't prompt if we can't // find the file, or the file doesn't have symbols (and we don't validate that @@ -243,7 +243,7 @@ StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, float *progress) while(search && search < dbend) { if(progress) - *progress = float(search - start) / float(DBSize); + progress(float(search - start) / float(DBSize)); // find .text segments { @@ -322,7 +322,7 @@ StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, float *progress) } if(progress) - *progress = RDCMIN(1.0f, float(search - start) / float(DBSize)); + progress(RDCMIN(1.0f, float(search - start) / float(DBSize))); if(search >= dbend) break; diff --git a/renderdoc/os/win32/win32_callstack.cpp b/renderdoc/os/win32/win32_callstack.cpp index 91130749d..d074f9420 100644 --- a/renderdoc/os/win32/win32_callstack.cpp +++ b/renderdoc/os/win32/win32_callstack.cpp @@ -369,7 +369,7 @@ private: class Win32CallstackResolver : public Callstack::StackResolver { public: - Win32CallstackResolver(byte *moduleDB, size_t DBSize, float *progress); + Win32CallstackResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress); ~Win32CallstackResolver(); Callstack::AddressDetails GetAddr(uint64_t addr); @@ -675,7 +675,8 @@ wstring Win32CallstackResolver::pdbBrowse(wstring startingPoint) return outBuf; } -Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, float *progress) +Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, + RENDERDOC_ProgressCallback progress) { wstring configPath = StringFormat::UTF82Wide(FileIO::GetAppFolderFilename("config.ini")); { @@ -722,7 +723,7 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, fl modName = (WCHAR *)(chunks + sizeof(EnumModChunk)); if(progress) - *progress = float(chunks - moduleDB) / float(end - moduleDB); + progress(float(chunks - moduleDB) / float(end - moduleDB)); Module m; @@ -851,7 +852,7 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, fl } if(progress) - *progress = RDCMIN(1.0f, float(chunks - moduleDB) / float(end - moduleDB)); + progress(RDCMIN(1.0f, float(chunks - moduleDB) / float(end - moduleDB))); DIA2::SetBaseAddress(m.moduleId, chunk->base); @@ -962,7 +963,7 @@ Stackwalk *Create() return new Win32Callstack(NULL, 0); } -StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, float *progress) +StackResolver *MakeResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) { if(DBSize < 8 || memcmp(moduleDB, "WN32CALL", 8)) { diff --git a/renderdoc/replay/capture_file.cpp b/renderdoc/replay/capture_file.cpp index 5405ddd15..225d7173e 100644 --- a/renderdoc/replay/capture_file.cpp +++ b/renderdoc/replay/capture_file.cpp @@ -120,12 +120,13 @@ public: ReplaySupport LocalReplaySupport() { return m_Support; } const char *DriverName() { return m_DriverName.c_str(); } const char *RecordedMachineIdent() { return m_Ident.c_str(); } - rdcpair OpenCapture(float *progress); + rdcpair OpenCapture(RENDERDOC_ProgressCallback progress); void SetMetadata(const char *driverName, uint64_t machineIdent, FileType thumbType, uint32_t thumbWidth, uint32_t thumbHeight, const bytebuf &thumbData); - ReplayStatus Convert(const char *filename, const char *filetype, float *progress); + ReplayStatus Convert(const char *filename, const char *filetype, + RENDERDOC_ProgressCallback progress); rdcarray GetCaptureFileFormats() { @@ -175,7 +176,7 @@ public: void WriteSection(const SectionProperties &props, const bytebuf &contents); bool HasCallstacks(); - bool InitResolver(float *progress); + bool InitResolver(RENDERDOC_ProgressCallback progress); rdcarray GetResolve(const rdcarray &callstack); private: @@ -324,7 +325,7 @@ ReplayStatus CaptureFile::Init() return ReplayStatus::InternalError; } -rdcpair CaptureFile::OpenCapture(float *progress) +rdcpair CaptureFile::OpenCapture(RENDERDOC_ProgressCallback progress) { if(!m_RDC || m_RDC->ErrorCode() != ContainerError::NoError) return make_rdcpair(ReplayStatus::InternalError, NULL); @@ -332,11 +333,11 @@ rdcpair CaptureFile::OpenCapture(float *progr ReplayController *render = new ReplayController(); ReplayStatus ret; - RenderDoc::Inst().SetProgressPointer(progress); + RenderDoc::Inst().SetProgressCallback(progress); ret = render->CreateDevice(m_RDC); - RenderDoc::Inst().SetProgressPointer(NULL); + RenderDoc::Inst().SetProgressCallback(RENDERDOC_ProgressCallback()); if(ret != ReplayStatus::Succeeded) SAFE_DELETE(render); @@ -376,7 +377,8 @@ void CaptureFile::SetMetadata(const char *driverName, uint64_t machineIdent, Fil free((void *)th.pixels); } -ReplayStatus CaptureFile::Convert(const char *filename, const char *filetype, float *progress) +ReplayStatus CaptureFile::Convert(const char *filename, const char *filetype, + RENDERDOC_ProgressCallback progress) { if(!m_RDC) { @@ -678,7 +680,7 @@ bool CaptureFile::HasCallstacks() return m_RDC && m_RDC->SectionIndex(SectionType::ResolveDatabase) >= 0; } -bool CaptureFile::InitResolver(float *progress) +bool CaptureFile::InitResolver(RENDERDOC_ProgressCallback progress) { if(!HasCallstacks()) { @@ -687,7 +689,7 @@ bool CaptureFile::InitResolver(float *progress) } if(progress) - *progress = 0.001f; + progress(0.001f); int idx = m_RDC->SectionIndex(SectionType::ResolveDatabase); @@ -709,7 +711,7 @@ bool CaptureFile::InitResolver(float *progress) } if(progress) - *progress = 0.002f; + progress(0.002f); m_Resolver = Callstack::MakeResolver(buf.data(), buf.size(), progress); diff --git a/renderdoc/replay/entry_points.cpp b/renderdoc/replay/entry_points.cpp index 99fe1d965..ba3b0aaf7 100644 --- a/renderdoc/replay/entry_points.cpp +++ b/renderdoc/replay/entry_points.cpp @@ -400,22 +400,20 @@ extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_GetDefaultRemoteServerP return RenderDoc_RemoteServerPort; } -extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_BecomeRemoteServer(const char *listenhost, - uint32_t port, - volatile bool *killReplay) +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_BecomeRemoteServer( + const char *listenhost, uint32_t port, RENDERDOC_KillCallback killReplay) { - bool dummy = false; - - if(killReplay == NULL) - killReplay = &dummy; - if(listenhost == NULL || listenhost[0] == 0) listenhost = "0.0.0.0"; + // ensure a sensible default if no callback is provided, that just never kills + if(!killReplay) + killReplay = []() { return false; }; + if(port == 0) port = RENDERDOC_GetDefaultRemoteServerPort(); - RenderDoc::Inst().BecomeRemoteServer(listenhost, (uint16_t)port, *killReplay); + RenderDoc::Inst().BecomeRemoteServer(listenhost, (uint16_t)port, killReplay); } extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartSelfHostCapture(const char *dllname) diff --git a/renderdoc/serialise/codecs/chrome_json_codec.cpp b/renderdoc/serialise/codecs/chrome_json_codec.cpp index f9e9bf2b3..ecda0d1aa 100644 --- a/renderdoc/serialise/codecs/chrome_json_codec.cpp +++ b/renderdoc/serialise/codecs/chrome_json_codec.cpp @@ -27,7 +27,7 @@ #include "serialise/rdcfile.h" ReplayStatus exportChrome(const char *filename, const RDCFile &rdc, const SDFile &structData, - float *progress) + RENDERDOC_ProgressCallback progress) { FILE *f = FileIO::fopen(filename, "w"); @@ -46,6 +46,9 @@ ReplayStatus exportChrome(const char *filename, const RDCFile &rdc, const SDFile // stupid JSON not allowing trailing ,s :( bool first = true; + int i = 0; + int numChunks = structData.chunks.count(); + for(const SDChunk *chunk : structData.chunks) { if(chunk->metadata.chunkID == (uint32_t)SystemChunk::FirstDriverChunk + 1) @@ -69,8 +72,16 @@ ReplayStatus exportChrome(const char *filename, const RDCFile &rdc, const SDFile str += StringFormat::Fmt( fmt, chunk->name.c_str(), category, chunk->metadata.timestampMicro, chunk->metadata.threadID, chunk->metadata.timestampMicro + chunk->metadata.durationMicro, chunk->metadata.threadID); + + if(progress) + progress(float(i) / float(numChunks)); + + i++; } + if(progress) + progress(1.0f); + // end trace events str += "\n ]\n}"; diff --git a/renderdoc/serialise/codecs/xml_codec.cpp b/renderdoc/serialise/codecs/xml_codec.cpp index b0879a834..9a905e16f 100644 --- a/renderdoc/serialise/codecs/xml_codec.cpp +++ b/renderdoc/serialise/codecs/xml_codec.cpp @@ -258,7 +258,8 @@ static void Obj2XML(pugi::xml_node &parent, SDObject &child) } static ReplayStatus Structured2XML(const char *filename, const RDCFile &file, uint64_t version, - const StructuredChunkList &chunks, float *progress) + const StructuredChunkList &chunks, + RENDERDOC_ProgressCallback progress) { pugi::xml_document doc; @@ -473,8 +474,9 @@ static SDObject *XML2Obj(pugi::xml_node &obj) return ret; } -static ReplayStatus XML2Structured(const char *xml, const StructuredBufferList &buffers, RDCFile *rdc, - uint64_t &version, StructuredChunkList &chunks, float *progress) +static ReplayStatus XML2Structured(const char *xml, const StructuredBufferList &buffers, + RDCFile *rdc, uint64_t &version, StructuredChunkList &chunks, + RENDERDOC_ProgressCallback progress) { pugi::xml_document doc; doc.load_string(xml); @@ -540,7 +542,7 @@ static ReplayStatus XML2Structured(const char *xml, const StructuredBufferList & pugi::xml_node xSection = xHeader.next_sibling(); if(progress) - *progress = StructuredProgress(0.1f); + progress(StructuredProgress(0.1f)); while(!strcmp(xSection.name(), "section")) { @@ -611,7 +613,7 @@ static ReplayStatus XML2Structured(const char *xml, const StructuredBufferList & } if(progress) - *progress = StructuredProgress(0.2f); + progress(StructuredProgress(0.2f)); pugi::xml_node xChunks = xSection; @@ -679,7 +681,7 @@ static ReplayStatus XML2Structured(const char *xml, const StructuredBufferList & chunks.push_back(chunk); if(progress) - *progress = StructuredProgress(0.2f + 0.8f * (float(chunkIdx) / float(numChunks))); + progress(StructuredProgress(0.2f + 0.8f * (float(chunkIdx) / float(numChunks)))); chunkIdx++; } @@ -688,7 +690,8 @@ static ReplayStatus XML2Structured(const char *xml, const StructuredBufferList & } static ReplayStatus Buffers2ZIP(const std::string &filename, const RDCFile &file, - const StructuredBufferList &buffers, float *progress) + const StructuredBufferList &buffers, + RENDERDOC_ProgressCallback progress) { std::string zipFile = filename + ".zip"; @@ -709,7 +712,7 @@ static ReplayStatus Buffers2ZIP(const std::string &filename, const RDCFile &file MZ_BEST_COMPRESSION); if(progress) - *progress = BufferProgress(float(i) / float(buffers.size())); + progress(BufferProgress(float(i) / float(buffers.size()))); } const RDCThumb &th = file.GetThumbnail(); @@ -722,7 +725,8 @@ static ReplayStatus Buffers2ZIP(const std::string &filename, const RDCFile &file return ReplayStatus::Succeeded; } -static void ZIP2Buffers(const std::string &filename, StructuredBufferList &buffers, float *progress) +static void ZIP2Buffers(const std::string &filename, StructuredBufferList &buffers, + RENDERDOC_ProgressCallback progress) { std::string zipFile = filename + ".zip"; @@ -767,7 +771,7 @@ static void ZIP2Buffers(const std::string &filename, StructuredBufferList &buffe } if(progress) - *progress = BufferProgress(float(i) / float(numfiles)); + progress(BufferProgress(float(i) / float(numfiles))); } } @@ -775,7 +779,7 @@ static void ZIP2Buffers(const std::string &filename, StructuredBufferList &buffe } ReplayStatus importXMLZ(const char *filename, StreamReader &reader, RDCFile *rdc, - SDFile &structData, float *progress) + SDFile &structData, RENDERDOC_ProgressCallback progress) { if(filename) ZIP2Buffers(filename, structData.buffers, progress); @@ -790,7 +794,7 @@ ReplayStatus importXMLZ(const char *filename, StreamReader &reader, RDCFile *rdc } ReplayStatus exportXMLZ(const char *filename, const RDCFile &rdc, const SDFile &structData, - float *progress) + RENDERDOC_ProgressCallback progress) { ReplayStatus ret = Buffers2ZIP(filename, rdc, structData.buffers, progress); diff --git a/renderdoc/serialise/serialiser.cpp b/renderdoc/serialise/serialiser.cpp index 86efce242..37f5774be 100644 --- a/renderdoc/serialise/serialiser.cpp +++ b/renderdoc/serialise/serialiser.cpp @@ -408,7 +408,8 @@ void Serialiser::EndChunk() } template <> -void Serialiser::WriteStructuredFile(const SDFile &file, float *progress) +void Serialiser::WriteStructuredFile(const SDFile &file, + RENDERDOC_ProgressCallback progress) { Serialiser scratchWriter( new StreamWriter(StreamWriter::DefaultScratchSize), Ownership::Stream); @@ -475,9 +476,12 @@ void Serialiser::WriteStructuredFile(const SDFile &file } if(progress) - *progress = float(i) / float(file.chunks.size()); + progress(float(i) / float(file.chunks.size())); } + if(progress) + progress(1.0f); + m_StructuredFile = &m_StructData; scratchWriter.m_StructuredFile = &scratchWriter.m_StructData; } diff --git a/renderdoc/serialise/serialiser.h b/renderdoc/serialise/serialiser.h index 2bd0a83b7..ae5edd266 100644 --- a/renderdoc/serialise/serialiser.h +++ b/renderdoc/serialise/serialiser.h @@ -132,7 +132,7 @@ public: // up-front void SetStreamingMode(bool stream) { m_DataStreaming = stream; } SDFile &GetStructuredFile() { return *m_StructuredFile; } - void WriteStructuredFile(const SDFile &file, float *progress); + void WriteStructuredFile(const SDFile &file, RENDERDOC_ProgressCallback progress); void SetDrawChunk() { m_DrawChunk = true; } ////////////////////////////////////////// // Public serialisation interface @@ -1208,7 +1208,8 @@ public: return SerialiseNullable(name, (T *&)el, flags); } - Serialiser &SerialiseStream(const std::string &name, StreamReader &stream, float *progress = NULL) + Serialiser &SerialiseStream(const std::string &name, StreamReader &stream, + RENDERDOC_ProgressCallback progress = RENDERDOC_ProgressCallback()) { RDCCOMPILE_ASSERT(IsWriting(), "Can't read into a StreamReader"); @@ -1228,7 +1229,8 @@ public: return *this; } - Serialiser &SerialiseStream(const std::string &name, StreamWriter &stream, float *progress = NULL) + Serialiser &SerialiseStream(const std::string &name, StreamWriter &stream, + RENDERDOC_ProgressCallback progress) { RDCCOMPILE_ASSERT(IsReading(), "Can't write from a StreamWriter"); @@ -1294,7 +1296,7 @@ public: byte *buf = new byte[byteSize]; if(progress) - *progress = 0.0001f; + progress(0.0001f); for(uint64_t i = 0; i < numBufs; i++) { @@ -1311,7 +1313,7 @@ public: totalSize -= payloadLength; if(progress) - *progress = float(i + 1) / float(numBufs); + progress(float(i + 1) / float(numBufs)); } delete[] buf; @@ -1319,7 +1321,7 @@ public: else { if(progress) - *progress = 1.0f; + progress(1.0f); } return *this; diff --git a/renderdoc/serialise/streamio.cpp b/renderdoc/serialise/streamio.cpp index 300890888..f0278fec4 100644 --- a/renderdoc/serialise/streamio.cpp +++ b/renderdoc/serialise/streamio.cpp @@ -488,7 +488,7 @@ void StreamWriter::HandleError() m_InMemory = false; } -void StreamTransfer(StreamWriter *writer, StreamReader *reader, float *progress) +void StreamTransfer(StreamWriter *writer, StreamReader *reader, RENDERDOC_ProgressCallback progress) { uint64_t totalSize = reader->GetSize(); @@ -504,7 +504,7 @@ void StreamTransfer(StreamWriter *writer, StreamReader *reader, float *progress) byte *buf = new byte[(size_t)bufSize]; if(progress) - *progress = 0.0001f; + progress(0.0001f); for(uint64_t i = 0; i < numBufs; i++) { @@ -515,8 +515,11 @@ void StreamTransfer(StreamWriter *writer, StreamReader *reader, float *progress) totalSize -= payloadLength; if(progress) - *progress = float(i + 1) / float(numBufs); + progress(float(i + 1) / float(numBufs)); } + if(progress) + progress(1.0f); + delete[] buf; } \ No newline at end of file diff --git a/renderdoc/serialise/streamio.h b/renderdoc/serialise/streamio.h index 571a16805..6ed59da2e 100644 --- a/renderdoc/serialise/streamio.h +++ b/renderdoc/serialise/streamio.h @@ -488,4 +488,4 @@ private: std::vector m_Callbacks; }; -void StreamTransfer(StreamWriter *writer, StreamReader *reader, float *progress); \ No newline at end of file +void StreamTransfer(StreamWriter *writer, StreamReader *reader, RENDERDOC_ProgressCallback progress); \ No newline at end of file diff --git a/renderdoccmd/renderdoccmd.cpp b/renderdoccmd/renderdoccmd.cpp index 15649c19a..b82e229f7 100644 --- a/renderdoccmd/renderdoccmd.cpp +++ b/renderdoccmd/renderdoccmd.cpp @@ -499,7 +499,8 @@ struct RemoteServerCommand : public Command usingKillSignal = true; - RENDERDOC_BecomeRemoteServer(host.empty() ? NULL : host.c_str(), port, &killSignal); + RENDERDOC_BecomeRemoteServer(host.empty() ? NULL : host.c_str(), port, + []() { return killSignal; }); std::cerr << std::endl << "Cleaning up from replay hosting." << std::endl;