diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index 6c50a55af..1cb850ed2 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -3375,7 +3375,7 @@ capture's API. protected: ICaptureContext() = default; - ~ICaptureContext() = default; + virtual ~ICaptureContext() = default; }; DECLARE_REFLECTION_STRUCT(ICaptureContext); diff --git a/qrenderdoc/Code/pyrenderdoc/PythonInvokers.cpp b/qrenderdoc/Code/pyrenderdoc/PythonInvokers.cpp new file mode 100644 index 000000000..493b208f6 --- /dev/null +++ b/qrenderdoc/Code/pyrenderdoc/PythonInvokers.cpp @@ -0,0 +1,1830 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2017-2026 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include "Code/pyrenderdoc/PythonContext.h" +#include "Windows/PythonShell.h" + +// a forwarder that invokes onto the UI thread wherever necessary. +// Note this does NOT make CaptureContext thread safe. We just invoke for any potentially UI +// operations. All invokes are blocking, so there can't be any times when the UI thread waits +// on the python thread. +template +struct UIThreadInvoker : Obj +{ + UIThreadInvoker(PythonShell *sh, Obj &o) : m_Shell(sh), m_Obj(o) {} + virtual ~UIThreadInvoker() {} + PythonShell *m_Shell; + Obj &m_Obj; + + template + void InvokeVoidFunction(F ptr, paramTypes... params) + { + if(!GUIInvoke::onUIThread()) + { + PythonContext *scriptContext = m_Shell->GetScriptContext(); + if(scriptContext) + scriptContext->PausePythonThreading(); + GUIInvoke::blockcall(m_Shell, [this, ptr, params...]() { (m_Obj.*ptr)(params...); }); + if(scriptContext) + scriptContext->ResumePythonThreading(); + return; + } + + (m_Obj.*ptr)(params...); + } + + template + R InvokeRetFunction(F ptr, paramTypes... params) + { + if(!GUIInvoke::onUIThread()) + { + R ret; + PythonContext *scriptContext = m_Shell->GetScriptContext(); + if(scriptContext) + scriptContext->PausePythonThreading(); + GUIInvoke::blockcall(m_Shell, + [this, &ret, ptr, params...]() { ret = (m_Obj.*ptr)(params...); }); + if(scriptContext) + scriptContext->ResumePythonThreading(); + return ret; + } + + return (m_Obj.*ptr)(params...); + } +}; + +struct MiniQtInvoker : UIThreadInvoker +{ + MiniQtInvoker(PythonShell *shell, IMiniQtHelper &obj) : UIThreadInvoker(shell, obj) {} + virtual ~MiniQtInvoker() {} + void InvokeOntoUIThread(std::function callback) + { + // this function is already thread safe since it's invoking, so just call it directly + m_Obj.InvokeOntoUIThread(callback); + } + + /////////////////////////////////////////////////////////////////////// + // all functions invoke onto the UI thread since they deal with widgets! + /////////////////////////////////////////////////////////////////////// + + QWidget *CreateToplevelWidget(const rdcstr &windowTitle, WidgetCallback closed) + { + return InvokeRetFunction(&IMiniQtHelper::CreateToplevelWidget, windowTitle, closed); + } + void CloseToplevelWidget(QWidget *widget) + { + InvokeVoidFunction(&IMiniQtHelper::CloseToplevelWidget, widget); + } + + // widget hierarchy + + void SetWidgetName(QWidget *widget, const rdcstr &name) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetName, widget, name); + } + rdcstr GetWidgetName(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::GetWidgetName, widget); + } + rdcstr GetWidgetType(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::GetWidgetType, widget); + } + QWidget *FindChildByName(QWidget *parent, const rdcstr &name) + { + return InvokeRetFunction(&IMiniQtHelper::FindChildByName, parent, name); + } + QWidget *GetParent(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::GetParent, widget); + } + int32_t GetNumChildren(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::GetNumChildren, widget); + } + QWidget *GetChild(QWidget *parent, int32_t index) + { + return InvokeRetFunction(&IMiniQtHelper::GetChild, parent, index); + } + void DestroyWidget(QWidget *widget) { InvokeVoidFunction(&IMiniQtHelper::DestroyWidget, widget); } + // dialogs + + bool ShowWidgetAsDialog(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::ShowWidgetAsDialog, widget); + } + void CloseCurrentDialog(bool success) + { + InvokeVoidFunction(&IMiniQtHelper::CloseCurrentDialog, success); + } + + // layout functions + + QWidget *CreateHorizontalContainer() + { + return InvokeRetFunction(&IMiniQtHelper::CreateHorizontalContainer); + } + QWidget *CreateVerticalContainer() + { + return InvokeRetFunction(&IMiniQtHelper::CreateVerticalContainer); + } + QWidget *CreateGridContainer() + { + return InvokeRetFunction(&IMiniQtHelper::CreateGridContainer); + } + QWidget *CreateSpacer(bool horizontal) + { + return InvokeRetFunction(&IMiniQtHelper::CreateSpacer, horizontal); + } + void ClearContainedWidgets(QWidget *parent) + { + InvokeVoidFunction(&IMiniQtHelper::ClearContainedWidgets, parent); + } + void AddGridWidget(QWidget *parent, int32_t row, int32_t column, QWidget *child, int32_t rowSpan, + int32_t columnSpan) + { + InvokeVoidFunction(&IMiniQtHelper::AddGridWidget, parent, row, column, child, rowSpan, + columnSpan); + } + void AddWidget(QWidget *parent, QWidget *child) + { + InvokeVoidFunction(&IMiniQtHelper::AddWidget, parent, child); + } + void InsertWidget(QWidget *parent, int32_t index, QWidget *child) + { + InvokeVoidFunction(&IMiniQtHelper::InsertWidget, parent, index, child); + } + + // widget manipulation + + void SetWidgetText(QWidget *widget, const rdcstr &text) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetText, widget, text); + } + rdcstr GetWidgetText(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::GetWidgetText, widget); + } + + void SetWidgetFont(QWidget *widget, const rdcstr &font, int32_t fontSize, bool bold, bool italic) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetFont, widget, font, fontSize, bold, italic); + } + + void SetWidgetEnabled(QWidget *widget, bool enabled) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetEnabled, widget, enabled); + } + bool IsWidgetEnabled(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::IsWidgetEnabled, widget); + } + void SetWidgetVisible(QWidget *widget, bool visible) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetVisible, widget, visible); + } + bool IsWidgetVisible(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::IsWidgetVisible, widget); + } + + // specific widgets + + QWidget *CreateGroupBox(bool collapsible) + { + return InvokeRetFunction(&IMiniQtHelper::CreateGroupBox, collapsible); + } + + QWidget *CreateButton(WidgetCallback pressed) + { + return InvokeRetFunction(&IMiniQtHelper::CreateButton, pressed); + } + + QWidget *CreateLabel() { return InvokeRetFunction(&IMiniQtHelper::CreateLabel); } + void SetLabelImage(QWidget *widget, const bytebuf &data, int32_t width, int32_t height, bool alpha) + { + InvokeVoidFunction(&IMiniQtHelper::SetLabelImage, widget, data, width, height, alpha); + } + QWidget *CreateOutputRenderingWidget() + { + return InvokeRetFunction(&IMiniQtHelper::CreateOutputRenderingWidget); + } + WindowingData GetWidgetWindowingData(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::GetWidgetWindowingData, widget); + } + + void SetWidgetReplayOutput(QWidget *widget, IReplayOutput *output) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetReplayOutput, widget, output); + } + + void SetWidgetBackgroundColor(QWidget *widget, float red, float green, float blue) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetBackgroundColor, widget, red, green, blue); + } + QWidget *CreateCheckbox(WidgetCallback changed) + { + return InvokeRetFunction(&IMiniQtHelper::CreateCheckbox, changed); + } + QWidget *CreateRadiobox(WidgetCallback changed) + { + return InvokeRetFunction(&IMiniQtHelper::CreateRadiobox, changed); + } + + void SetWidgetChecked(QWidget *checkableWidget, bool checked) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetChecked, checkableWidget, checked); + } + bool IsWidgetChecked(QWidget *checkableWidget) + { + return InvokeRetFunction(&IMiniQtHelper::IsWidgetChecked, checkableWidget); + } + + QWidget *CreateSpinbox(int32_t decimalPlaces, double step) + { + return InvokeRetFunction(&IMiniQtHelper::CreateSpinbox, decimalPlaces, step); + } + + void SetSpinboxBounds(QWidget *spinbox, double minVal, double maxVal) + { + InvokeVoidFunction(&IMiniQtHelper::SetSpinboxBounds, spinbox, minVal, maxVal); + } + void SetSpinboxValue(QWidget *spinbox, double value) + { + InvokeVoidFunction(&IMiniQtHelper::SetSpinboxValue, spinbox, value); + } + double GetSpinboxValue(QWidget *spinbox) + { + return InvokeRetFunction(&IMiniQtHelper::GetSpinboxValue, spinbox); + } + + QWidget *CreateTextBox(bool singleLine, WidgetCallback changed) + { + return InvokeRetFunction(&IMiniQtHelper::CreateTextBox, singleLine, changed); + } + + QWidget *CreateComboBox(bool editable, WidgetCallback changed) + { + return InvokeRetFunction(&IMiniQtHelper::CreateComboBox, editable, changed); + } + + void SetComboOptions(QWidget *combo, const rdcarray &options) + { + InvokeVoidFunction(&IMiniQtHelper::SetComboOptions, combo, options); + } + + size_t GetComboCount(QWidget *combo) + { + return InvokeRetFunction(&IMiniQtHelper::GetComboCount, combo); + } + + void SelectComboOption(QWidget *combo, const rdcstr &option) + { + InvokeVoidFunction(&IMiniQtHelper::SelectComboOption, combo, option); + } + + QWidget *CreateProgressBar(bool horizontal) + { + return InvokeRetFunction(&IMiniQtHelper::CreateProgressBar, horizontal); + } + + void ResetProgressBar(QWidget *pbar) + { + InvokeVoidFunction(&IMiniQtHelper::ResetProgressBar, pbar); + } + + void SetProgressBarValue(QWidget *pbar, int32_t value) + { + InvokeVoidFunction(&IMiniQtHelper::SetProgressBarValue, pbar, value); + } + + void UpdateProgressBarValue(QWidget *pbar, int32_t delta) + { + InvokeVoidFunction(&IMiniQtHelper::UpdateProgressBarValue, pbar, delta); + } + + int32_t GetProgressBarValue(QWidget *pbar) + { + return InvokeRetFunction(&IMiniQtHelper::GetProgressBarValue, pbar); + } + + void SetProgressBarRange(QWidget *pbar, int32_t minimum, int32_t maximum) + { + InvokeVoidFunction(&IMiniQtHelper::SetProgressBarRange, pbar, minimum, maximum); + } + + int32_t GetProgressBarMinimum(QWidget *pbar) + { + return InvokeRetFunction(&IMiniQtHelper::GetProgressBarMinimum, pbar); + } + + int32_t GetProgressBarMaximum(QWidget *pbar) + { + return InvokeRetFunction(&IMiniQtHelper::GetProgressBarMaximum, pbar); + } +}; + +struct ExtensionInvoker : UIThreadInvoker +{ + MiniQtInvoker *m_MiniQt; + ExtensionInvoker(PythonShell *shell, IExtensionManager &obj) : UIThreadInvoker(shell, obj) + { + m_MiniQt = new MiniQtInvoker(shell, obj.GetMiniQtHelper()); + } + virtual ~ExtensionInvoker() { delete m_MiniQt; } + // + /////////////////////////////////////////////////////////////////////// + // pass-through functions that don't need the UI thread + /////////////////////////////////////////////////////////////////////// + // + rdcarray GetInstalledExtensions() { return m_Obj.GetInstalledExtensions(); } + rdcarray GetLoadedExtensions() { return m_Obj.GetLoadedExtensions(); } + bool IsExtensionLoaded(rdcstr name) { return m_Obj.IsExtensionLoaded(name); } + rdcstr LoadExtension(rdcstr name) { return m_Obj.LoadExtension(name); } + bool IsPythonDebuggerConnected() { return m_Obj.IsPythonDebuggerConnected(); } + IMiniQtHelper &GetMiniQtHelper() { return *m_MiniQt; } + // + /////////////////////////////////////////////////////////////////////// + // functions that invoke onto the UI thread + /////////////////////////////////////////////////////////////////////// + // + void RegisterWindowMenu(WindowMenu base, const rdcarray &submenus, + ExtensionCallback callback) + { + InvokeVoidFunction(&IExtensionManager::RegisterWindowMenu, base, submenus, callback); + } + + void RegisterPanelMenu(PanelMenu base, const rdcarray &submenus, ExtensionCallback callback) + { + InvokeVoidFunction(&IExtensionManager::RegisterPanelMenu, base, submenus, callback); + } + + void RegisterContextMenu(ContextMenu base, const rdcarray &submenus, + ExtensionCallback callback) + { + InvokeVoidFunction(&IExtensionManager::RegisterContextMenu, base, submenus, callback); + } + + void MessageDialog(const rdcstr &text, const rdcstr &title) + { + InvokeVoidFunction(&IExtensionManager::MessageDialog, text, title); + } + + void ErrorDialog(const rdcstr &text, const rdcstr &title) + { + InvokeVoidFunction(&IExtensionManager::ErrorDialog, text, title); + } + + DialogButton QuestionDialog(const rdcstr &text, const rdcarray &options, + const rdcstr &title) + { + return InvokeRetFunction(&IExtensionManager::QuestionDialog, text, options, title); + } + + rdcstr OpenFileName(const rdcstr &caption, const rdcstr &dir, const rdcstr &filter) + { + return InvokeRetFunction(&IExtensionManager::OpenFileName, caption, dir, filter); + } + + rdcstr OpenDirectoryName(const rdcstr &caption, const rdcstr &dir) + { + return InvokeRetFunction(&IExtensionManager::OpenDirectoryName, caption, dir); + } + + rdcstr SaveFileName(const rdcstr &caption, const rdcstr &dir, const rdcstr &filter) + { + return InvokeRetFunction(&IExtensionManager::SaveFileName, caption, dir, filter); + } + + void MenuDisplaying(ContextMenu contextMenu, QMenu *menu, const ExtensionCallbackData &data) + { + InvokeVoidFunction( + (void(IExtensionManager::*)(ContextMenu, QMenu *, const ExtensionCallbackData &)) & + IExtensionManager::MenuDisplaying, + contextMenu, menu, data); + } + void MenuDisplaying(PanelMenu panelMenu, QMenu *menu, QWidget *extensionButton, + const ExtensionCallbackData &data) + { + InvokeVoidFunction( + (void(IExtensionManager::*)(PanelMenu, QMenu *, QWidget *, const ExtensionCallbackData &)) & + IExtensionManager::MenuDisplaying, + panelMenu, menu, extensionButton, data); + } +}; + +struct ReplayControllerInvoker : IReplayController +{ + ReplayControllerInvoker(PythonShell *shell, ICaptureContext &ctx) : m_Shell(shell), m_Ctx(ctx) {} + virtual ~ReplayControllerInvoker() {} + PythonShell *m_Shell; + ICaptureContext &m_Ctx; + + template + void InvokeVoidFunction(F ptr, paramTypes... params) + { + PythonContext *scriptContext = m_Shell->GetScriptContext(); + if(scriptContext) + scriptContext->PausePythonThreading(); + m_Ctx.Replay().BlockInvoke( + [this, ptr, params...](IReplayController *replay) { (replay->*ptr)(params...); }); + if(scriptContext) + scriptContext->ResumePythonThreading(); + } + + template + R InvokeRetFunction(F ptr, paramTypes... params) + { + R ret = R(); + PythonContext *scriptContext = m_Shell->GetScriptContext(); + if(scriptContext) + scriptContext->PausePythonThreading(); + m_Ctx.Replay().BlockInvoke([this, &ret, ptr, params...](IReplayController *replay) { + ret = (replay->*ptr)(params...); + }); + if(scriptContext) + scriptContext->ResumePythonThreading(); + return ret; + } + + template + R &InvokeRetRefFunction(F ptr, paramTypes... params) + { + R *ret = NULL; + PythonContext *scriptContext = m_Shell->GetScriptContext(); + if(scriptContext) + scriptContext->PausePythonThreading(); + m_Ctx.Replay().BlockInvoke([this, &ret, ptr, params...](IReplayController *replay) { + ret = &(replay->*ptr)(params...); + }); + if(scriptContext) + scriptContext->ResumePythonThreading(); + return *ret; + } + + APIProperties GetAPIProperties() + { + return InvokeRetFunction(&IReplayController::GetAPIProperties); + } + + rdcarray GetSupportedWindowSystems() + { + return InvokeRetFunction>(&IReplayController::GetSupportedWindowSystems); + } + + IReplayOutput *CreateOutput(WindowingData window, ReplayOutputType type) + { + return InvokeRetFunction(&IReplayController::CreateOutput, window, type); + } + + void Shutdown() {} + + void ReplayLoop(WindowingData window, ResourceId texid) {} + + rdcstr CreateRGPProfile(WindowingData window) + { + return InvokeRetFunction(&IReplayController::CreateRGPProfile, window); + } + + void CancelReplayLoop() {} + + void FileChanged() {} + + void SetFrameEvent(uint32_t eventId, bool force) {} + + const D3D11Pipe::State *GetD3D11PipelineState() + { + return InvokeRetFunction(&IReplayController::GetD3D11PipelineState); + } + + const D3D12Pipe::State *GetD3D12PipelineState() + { + return InvokeRetFunction(&IReplayController::GetD3D12PipelineState); + } + + const GLPipe::State *GetGLPipelineState() + { + return InvokeRetFunction(&IReplayController::GetGLPipelineState); + } + + const VKPipe::State *GetVulkanPipelineState() + { + return InvokeRetFunction(&IReplayController::GetVulkanPipelineState); + } + + const PipeState &GetPipelineState() + { + return InvokeRetRefFunction(&IReplayController::GetPipelineState); + } + + rdcarray GetDescriptors(ResourceId descriptorStore, + const rdcarray &ranges) + { + return InvokeRetFunction>(&IReplayController::GetDescriptors, + descriptorStore, ranges); + } + + rdcarray GetSamplerDescriptors(ResourceId descriptorStore, + const rdcarray &ranges) + { + return InvokeRetFunction>(&IReplayController::GetSamplerDescriptors, + descriptorStore, ranges); + } + + const rdcarray &GetDescriptorAccess() + { + return InvokeRetRefFunction>( + &IReplayController::GetDescriptorAccess); + } + + rdcarray GetDescriptorLocations(ResourceId descriptorStore, + const rdcarray &ranges) + { + return InvokeRetFunction>( + &IReplayController::GetDescriptorLocations, descriptorStore, ranges); + } + + rdcarray GetDisassemblyTargets(bool withPipeline) + { + return InvokeRetFunction>(&IReplayController::GetDisassemblyTargets, + withPipeline); + } + + rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target) + { + return InvokeRetFunction(&IReplayController::DisassembleShader, pipeline, refl, target); + } + + void SetCustomShaderIncludes(const rdcarray &directories) {} + + rdcpair BuildCustomShader(const rdcstr &entry, ShaderEncoding sourceEncoding, + bytebuf source, + const ShaderCompileFlags &compileFlags, + ShaderStage type) + { + return InvokeRetFunction>( + &IReplayController::BuildCustomShader, entry, sourceEncoding, source, compileFlags, type); + } + + void FreeCustomShader(ResourceId id) {} + + rdcpair BuildTargetShader(const rdcstr &entry, ShaderEncoding sourceEncoding, + bytebuf source, + const ShaderCompileFlags &compileFlags, + ShaderStage type) + { + return InvokeRetFunction>( + &IReplayController::BuildTargetShader, entry, sourceEncoding, source, compileFlags, type); + } + + rdcarray GetTargetShaderEncodings() + { + return InvokeRetFunction>(&IReplayController::GetTargetShaderEncodings); + } + + rdcarray GetCustomShaderEncodings() + { + return InvokeRetFunction>(&IReplayController::GetCustomShaderEncodings); + } + + rdcarray GetCustomShaderSourcePrefixes() + { + return InvokeRetFunction>( + &IReplayController::GetCustomShaderSourcePrefixes); + } + + void ReplaceResource(ResourceId original, ResourceId replacement) {} + + void ClearReplayCache() {} + + void ReloadShaderDebugInformation() {} + + void RemoveReplacement(ResourceId id) {} + + void FreeTargetResource(ResourceId id) {} + + FrameDescription GetFrameInfo() + { + return InvokeRetFunction(&IReplayController::GetFrameInfo); + } + + const SDFile &GetStructuredFile() + { + return InvokeRetRefFunction(&IReplayController::GetStructuredFile); + } + + void AddFakeMarkers() {} + + const rdcarray &GetRootActions() + { + return InvokeRetRefFunction>(&IReplayController::GetRootActions); + } + + rdcarray FetchCounters(const rdcarray &counters) + { + return InvokeRetFunction>(&IReplayController::FetchCounters, counters); + } + + rdcarray EnumerateCounters() + { + return InvokeRetFunction>(&IReplayController::EnumerateCounters); + } + + CounterDescription DescribeCounter(GPUCounter counter) + { + return InvokeRetFunction(&IReplayController::DescribeCounter, counter); + } + + const rdcarray &GetResources() + { + return InvokeRetRefFunction>(&IReplayController::GetResources); + } + + const rdcarray &GetTextures() + { + return InvokeRetRefFunction>(&IReplayController::GetTextures); + } + + const rdcarray &GetBuffers() + { + return InvokeRetRefFunction>(&IReplayController::GetBuffers); + } + + const rdcarray &GetDescriptorStores() + { + return InvokeRetRefFunction>( + &IReplayController::GetDescriptorStores); + } + + rdcarray GetDebugMessages() + { + return InvokeRetFunction>(&IReplayController::GetDebugMessages); + } + + ResultDetails GetFatalErrorStatus() + { + return InvokeRetFunction(&IReplayController::GetFatalErrorStatus); + } + + rdcarray GetShaderEntryPoints(ResourceId shader) + { + return InvokeRetFunction>(&IReplayController::GetShaderEntryPoints, + shader); + } + + const ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry) + { + return InvokeRetFunction(&IReplayController::GetShader, pipeline, + shader, entry); + } + + PixelValue PickPixel(ResourceId textureId, uint32_t x, uint32_t y, const Subresource &sub, + CompType typeCast) + { + return InvokeRetFunction(&IReplayController::PickPixel, textureId, x, y, sub, + typeCast); + } + + rdcpair GetMinMax(ResourceId textureId, const Subresource &sub, + CompType typeCast) + { + return InvokeRetFunction>(&IReplayController::GetMinMax, + textureId, sub, typeCast); + } + + rdcarray GetHistogram(ResourceId textureId, const Subresource &sub, CompType typeCast, + float minval, float maxval, const rdcfixedarray &channels) + { + return InvokeRetFunction>(&IReplayController::GetHistogram, textureId, sub, + typeCast, minval, maxval, channels); + } + + rdcarray PixelHistory(ResourceId texture, uint32_t x, uint32_t y, + const Subresource &sub, CompType typeCast) + { + return InvokeRetFunction>(&IReplayController::PixelHistory, texture, + x, y, sub, typeCast); + } + + ShaderDebugTrace *DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t view) + { + return InvokeRetFunction(&IReplayController::DebugVertex, vertid, instid, + idx, view); + } + + ShaderDebugTrace *DebugPixel(uint32_t x, uint32_t y, const DebugPixelInputs &inputs) + { + return InvokeRetFunction(&IReplayController::DebugPixel, x, y, inputs); + } + + ShaderDebugTrace *DebugThread(const rdcfixedarray &groupid, + const rdcfixedarray &threadid) + { + return InvokeRetFunction(&IReplayController::DebugThread, groupid, threadid); + } + + ShaderDebugTrace *DebugMeshThread(const rdcfixedarray &groupid, + const rdcfixedarray &threadid) + { + return InvokeRetFunction(&IReplayController::DebugMeshThread, groupid, + threadid); + } + + rdcarray ContinueDebug(ShaderDebugger *debugger) + { + return InvokeRetFunction>(&IReplayController::ContinueDebug, debugger); + } + + void FreeTrace(ShaderDebugTrace *trace) + { + return InvokeVoidFunction(&IReplayController::FreeTrace, trace); + } + + rdcarray GetUsage(ResourceId id) + { + return InvokeRetFunction>(&IReplayController::GetUsage, id); + } + + rdcarray GetCBufferVariableContents(ResourceId pipeline, ResourceId shader, + ShaderStage stage, const rdcstr &entryPoint, + uint32_t cbufslot, ResourceId buffer, + uint64_t offset, uint64_t length) + { + return InvokeRetFunction>( + &IReplayController::GetCBufferVariableContents, pipeline, shader, stage, entryPoint, + cbufslot, buffer, offset, length); + } + + ResultDetails SaveTexture(const TextureSave &saveData, const rdcstr &path) + { + return InvokeRetFunction(&IReplayController::SaveTexture, saveData, path); + } + + MeshFormat GetPostVSData(uint32_t instance, uint32_t view, MeshDataStage stage) + { + return InvokeRetFunction(&IReplayController::GetPostVSData, instance, view, stage); + } + + bytebuf GetBufferData(ResourceId buff, uint64_t offset, uint64_t len) + { + return InvokeRetFunction(&IReplayController::GetBufferData, buff, offset, len); + } + + bytebuf GetTextureData(ResourceId tex, const Subresource &sub) + { + return InvokeRetFunction(&IReplayController::GetTextureData, tex, sub); + } +}; + +struct IMainWindowInvoker : UIThreadInvoker +{ + IMainWindowInvoker(PythonShell *shell, IMainWindow &obj) : UIThreadInvoker(shell, obj) {} + virtual ~IMainWindowInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + void RegisterShortcut(const rdcstr &shortcut, QWidget *widget, ShortcutCallback callback) + { + return InvokeVoidFunction(&IMainWindow::RegisterShortcut, shortcut, widget, callback); + } + void UnregisterShortcut(const rdcstr &shortcut, QWidget *widget) + { + return InvokeVoidFunction(&IMainWindow::UnregisterShortcut, shortcut, widget); + } + void BringToFront() { return InvokeVoidFunction(&IMainWindow::BringToFront); } +}; + +struct IEventBrowserInvoker : UIThreadInvoker +{ + IEventBrowserInvoker(PythonShell *shell, IEventBrowser &obj) : UIThreadInvoker(shell, obj) {} + virtual ~IEventBrowserInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + void UpdateDurationColumn() { return InvokeVoidFunction(&IEventBrowser::UpdateDurationColumn); } + APIEvent GetAPIEventForEID(uint32_t eventId) + { + return InvokeRetFunction(&IEventBrowser::GetAPIEventForEID, eventId); + } + const ActionDescription *GetActionForEID(uint32_t eventId) + { + return InvokeRetFunction(&IEventBrowser::GetActionForEID, eventId); + } + rdcstr GetEventName(uint32_t eventId) + { + return InvokeRetFunction(&IEventBrowser::GetEventName, eventId); + } + bool IsAPIEventVisible(uint32_t eventId) + { + return InvokeRetFunction(&IEventBrowser::IsAPIEventVisible, eventId); + } + bool RegisterEventFilterFunction(const rdcstr &name, const rdcstr &description, + EventFilterCallback filter, FilterParseCallback parser, + AutoCompleteCallback completer) + { + return InvokeRetFunction(&IEventBrowser::RegisterEventFilterFunction, name, description, + filter, parser, completer); + } + bool UnregisterEventFilterFunction(const rdcstr &name) + { + return InvokeRetFunction(&IEventBrowser::UnregisterEventFilterFunction, name); + } + void SetCurrentFilterText(const rdcstr &text) + { + return InvokeVoidFunction(&IEventBrowser::SetCurrentFilterText, text); + }; + rdcstr GetCurrentFilterText() + { + return InvokeRetFunction(&IEventBrowser::GetCurrentFilterText); + } + void SetUseCustomActionNames(bool use) + { + return InvokeVoidFunction(&IEventBrowser::SetUseCustomActionNames, use); + } + void SetShowParameterNames(bool show) + { + return InvokeVoidFunction(&IEventBrowser::SetShowParameterNames, show); + } + void SetShowAllParameters(bool show) + { + return InvokeVoidFunction(&IEventBrowser::SetShowAllParameters, show); + } + void SetEmptyRegionsVisible(bool show) + { + return InvokeVoidFunction(&IEventBrowser::SetEmptyRegionsVisible, show); + } + void SetHighlightedAnnotation(const rdcstr &annotationPath) + { + return InvokeVoidFunction(&IEventBrowser::SetHighlightedAnnotation, annotationPath); + } + rdcstr GetHighlightedAnnotation() + { + return InvokeRetFunction(&IEventBrowser::GetHighlightedAnnotation); + } + void SetDurationColumnVisible(bool show) + { + return InvokeVoidFunction(&IEventBrowser::SetDurationColumnVisible, show); + } + void SetAnnotationColumnVisible(bool show) + { + return InvokeVoidFunction(&IEventBrowser::SetAnnotationColumnVisible, show); + } +}; + +struct IAPIInspectorInvoker : UIThreadInvoker +{ + IAPIInspectorInvoker(PythonShell *shell, IAPIInspector &obj) : UIThreadInvoker(shell, obj) {} + virtual ~IAPIInspectorInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + virtual void Refresh() { return InvokeVoidFunction(&IAPIInspector::Refresh); } + virtual void RevealParameter(SDObject *param) + { + return InvokeVoidFunction(&IAPIInspector::RevealParameter, param); + } +}; + +struct IAnnotationViewerInvoker : UIThreadInvoker +{ + IAnnotationViewerInvoker(PythonShell *shell, IAnnotationViewer &obj) : UIThreadInvoker(shell, obj) + { + } + virtual ~IAnnotationViewerInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + + void RevealAnnotation(const rdcstr &keyPath) + { + return InvokeVoidFunction(&IAnnotationViewer::RevealAnnotation, keyPath); + } +}; + +struct ITextureViewerInvoker : UIThreadInvoker +{ + ITextureViewerInvoker(PythonShell *shell, ITextureViewer &obj) : UIThreadInvoker(shell, obj) {} + virtual ~ITextureViewerInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + void ViewTexture(ResourceId resourceId, CompType typeCast, bool focus) + { + return InvokeVoidFunction(&ITextureViewer::ViewTexture, resourceId, typeCast, focus); + } + void ViewFollowedResource(FollowType followType, ShaderStage stage, int32_t index, + int32_t arrayElement) + { + return InvokeVoidFunction(&ITextureViewer::ViewFollowedResource, followType, stage, index, + arrayElement); + } + ResourceId GetCurrentResource() + { + return InvokeRetFunction(&ITextureViewer::GetCurrentResource); + } + Subresource GetSelectedSubresource() + { + return InvokeRetFunction(&ITextureViewer::GetSelectedSubresource); + } + void SetSelectedSubresource(Subresource sub) + { + return InvokeVoidFunction(&ITextureViewer::SetSelectedSubresource, sub); + } + void GotoLocation(uint32_t x, uint32_t y) + { + return InvokeVoidFunction(&ITextureViewer::GotoLocation, x, y); + } + rdcpair GetPickedLocation() + { + return InvokeRetFunction>(&ITextureViewer::GetPickedLocation); + } + DebugOverlay GetTextureOverlay() + { + return InvokeRetFunction(&ITextureViewer::GetTextureOverlay); + } + void SetTextureOverlay(DebugOverlay overlay) + { + return InvokeVoidFunction(&ITextureViewer::SetTextureOverlay, overlay); + } + bool IsZoomAutoFit() { return InvokeRetFunction(&ITextureViewer::IsZoomAutoFit); } + float GetZoomLevel() { return InvokeRetFunction(&ITextureViewer::GetZoomLevel); } + void SetZoomLevel(bool autofit, float zoom) + { + return InvokeVoidFunction(&ITextureViewer::SetZoomLevel, autofit, zoom); + } + rdcpair GetHistogramRange() + { + return InvokeRetFunction>(&ITextureViewer::GetHistogramRange); + } + void SetHistogramRange(float blackpoint, float whitepoint) + { + return InvokeVoidFunction(&ITextureViewer::SetHistogramRange, blackpoint, whitepoint); + } + uint32_t GetChannelVisibilityBits() + { + return InvokeRetFunction(&ITextureViewer::GetChannelVisibilityBits); + } + void SetChannelVisibility(bool red, bool green, bool blue, bool alpha) + { + return InvokeVoidFunction(&ITextureViewer::SetChannelVisibility, red, green, blue, alpha); + } +}; + +struct IBufferViewerInvoker : UIThreadInvoker +{ + IBufferViewerInvoker(PythonShell *shell, IBufferViewer &obj) : UIThreadInvoker(shell, obj) {} + virtual ~IBufferViewerInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + void ScrollToRow(int32_t row, MeshDataStage stage) + { + return InvokeVoidFunction(&IBufferViewer::ScrollToRow, row, stage); + } + void ScrollToColumn(int32_t column, MeshDataStage stage) + { + return InvokeVoidFunction(&IBufferViewer::ScrollToColumn, column, stage); + } + void ShowMeshData(MeshDataStage stage) + { + return InvokeVoidFunction(&IBufferViewer::ShowMeshData, stage); + } + void SetCurrentInstance(int32_t instance) + { + return InvokeVoidFunction(&IBufferViewer::SetCurrentInstance, instance); + } + void SetCurrentView(int32_t view) + { + return InvokeVoidFunction(&IBufferViewer::SetCurrentView, view); + } + void SetPreviewStage(MeshDataStage stage) + { + return InvokeVoidFunction(&IBufferViewer::SetPreviewStage, stage); + } +}; + +struct IPipelineStateViewerInvoker : UIThreadInvoker +{ + IPipelineStateViewerInvoker(PythonShell *shell, IPipelineStateViewer &obj) + : UIThreadInvoker(shell, obj) + { + } + virtual ~IPipelineStateViewerInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + virtual bool SaveShaderFile(const ShaderReflection *shader) + { + return InvokeRetFunction(&IPipelineStateViewer::SaveShaderFile, shader); + } + virtual void SelectPipelineStage(PipelineStage stage) + { + return InvokeVoidFunction(&IPipelineStateViewer::SelectPipelineStage, stage); + } +}; + +struct ICaptureConnectionInvoker : UIThreadInvoker +{ + ICaptureConnectionInvoker(PythonShell *shell, ICaptureConnection &obj) + : UIThreadInvoker(shell, obj) + { + // delete ourself when the connection dies + obj.RegisterClosedCallback([this](ICaptureConnection *) { delete this; }); + } + virtual ~ICaptureConnectionInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + void RegisterClosedCallback(ClosedCallback method) + { + return InvokeVoidFunction(&ICaptureConnection::RegisterClosedCallback, method); + } + bool IsConnected() { return InvokeRetFunction(&ICaptureConnection::IsConnected); } + void PreventAutoClose() { return InvokeVoidFunction(&ICaptureConnection::PreventAutoClose); } + rdcarray GetAPIs() + { + return InvokeRetFunction>(&ICaptureConnection::GetAPIs); + } + void QueueCapture(int frameNumber, int numFrames) + { + return InvokeVoidFunction(&ICaptureConnection::QueueCapture, frameNumber, numFrames); + } + void TimedCapture(float secondsDelay, int numFrames) + { + return InvokeVoidFunction(&ICaptureConnection::TimedCapture, secondsDelay, numFrames); + } + void CycleActiveWindow() { return InvokeVoidFunction(&ICaptureConnection::CycleActiveWindow); } + rdcstr Target() { return InvokeRetFunction(&ICaptureConnection::Target); } + rdcstr Hostname() { return InvokeRetFunction(&ICaptureConnection::Hostname); } + rdcstr FriendlyHostname() + { + return InvokeRetFunction(&ICaptureConnection::FriendlyHostname); + } + void Close(bool discardUnsaved) + { + return InvokeVoidFunction(&ICaptureConnection::Close, discardUnsaved); + } + rdcarray GetCaptures() + { + return InvokeRetFunction>(&ICaptureConnection::GetCaptures); + } + void OpenCapture(uint32_t ID) { return InvokeVoidFunction(&ICaptureConnection::OpenCapture, ID); } + void DeleteCapture(uint32_t ID, bool promptForSave) + { + return InvokeVoidFunction(&ICaptureConnection::DeleteCapture, ID, promptForSave); + } + void SaveCapture(uint32_t ID, rdcstr filename) + { + return InvokeVoidFunction(&ICaptureConnection::SaveCapture, ID, filename); + } + rdcarray GetChildProcesses() + { + return InvokeRetFunction>(&ICaptureConnection::GetChildProcesses); + } + ICaptureConnection *ConnectToChild(uint32_t pid) + { + ICaptureConnection *ret = + InvokeRetFunction(&ICaptureConnection::ConnectToChild, pid); + + if(!ret) + return ret; + + return new ICaptureConnectionInvoker(m_Shell, *ret); + } +}; + +struct ICaptureDialogInvoker : UIThreadInvoker +{ + ICaptureDialogInvoker(PythonShell *shell, ICaptureDialog &obj) : UIThreadInvoker(shell, obj) {} + virtual ~ICaptureDialogInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + bool IsInjectMode() { return InvokeRetFunction(&ICaptureDialog::IsInjectMode); } + void SetInjectMode(bool inject) + { + return InvokeVoidFunction(&ICaptureDialog::SetInjectMode, inject); + } + void SetExecutableFilename(const rdcstr &filename) + { + return InvokeVoidFunction(&ICaptureDialog::SetExecutableFilename, filename); + } + void SetWorkingDirectory(const rdcstr &dir) + { + return InvokeVoidFunction(&ICaptureDialog::SetWorkingDirectory, dir); + } + void SetCommandLine(const rdcstr &cmd) + { + return InvokeVoidFunction(&ICaptureDialog::SetCommandLine, cmd); + } + void SetEnvironmentModifications(const rdcarray &modifications) + { + return InvokeVoidFunction(&ICaptureDialog::SetEnvironmentModifications, modifications); + } + void SetSettings(CaptureSettings settings) + { + return InvokeVoidFunction(&ICaptureDialog::SetSettings, settings); + } + CaptureSettings Settings() + { + return InvokeRetFunction(&ICaptureDialog::Settings); + } + ICaptureConnection *Launch() + { + ICaptureConnection *ret = InvokeRetFunction(&ICaptureDialog::Launch); + + if(!ret) + return ret; + + return new ICaptureConnectionInvoker(m_Shell, *ret); + } + void LoadSettings(const rdcstr &filename) + { + return InvokeVoidFunction(&ICaptureDialog::LoadSettings, filename); + } + void SaveSettings(const rdcstr &filename) + { + return InvokeVoidFunction(&ICaptureDialog::SaveSettings, filename); + } + void UpdateGlobalHook() { return InvokeVoidFunction(&ICaptureDialog::UpdateGlobalHook); } + void UpdateRemoteHost() { return InvokeVoidFunction(&ICaptureDialog::UpdateRemoteHost); } +}; + +struct IDebugMessageViewInvoker : UIThreadInvoker +{ + IDebugMessageViewInvoker(PythonShell *shell, IDebugMessageView &obj) : UIThreadInvoker(shell, obj) + { + } + virtual ~IDebugMessageViewInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } +}; + +struct IDiagnosticLogViewInvoker : UIThreadInvoker +{ + IDiagnosticLogViewInvoker(PythonShell *shell, IDiagnosticLogView &obj) + : UIThreadInvoker(shell, obj) + { + } + virtual ~IDiagnosticLogViewInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } +}; + +struct ICommentViewInvoker : UIThreadInvoker +{ + ICommentViewInvoker(PythonShell *shell, ICommentView &obj) : UIThreadInvoker(shell, obj) {} + virtual ~ICommentViewInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + virtual void SetComments(const rdcstr &text) + { + return InvokeVoidFunction(&ICommentView::SetComments, text); + } + virtual rdcstr GetComments() { return InvokeRetFunction(&ICommentView::GetComments); } +}; + +struct IPerformanceCounterViewerInvoker : UIThreadInvoker +{ + IPerformanceCounterViewerInvoker(PythonShell *shell, IPerformanceCounterViewer &obj) + : UIThreadInvoker(shell, obj) + { + } + virtual ~IPerformanceCounterViewerInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + void UpdateDurationColumn() + { + return InvokeVoidFunction(&IPerformanceCounterViewer::UpdateDurationColumn); + } +}; + +struct IStatisticsViewerInvoker : UIThreadInvoker +{ + IStatisticsViewerInvoker(PythonShell *shell, IStatisticsViewer &obj) : UIThreadInvoker(shell, obj) + { + } + virtual ~IStatisticsViewerInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } +}; + +struct ITimelineBarInvoker : UIThreadInvoker +{ + ITimelineBarInvoker(PythonShell *shell, ITimelineBar &obj) : UIThreadInvoker(shell, obj) {} + virtual ~ITimelineBarInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + void HighlightResourceUsage(ResourceId id) + { + return InvokeVoidFunction(&ITimelineBar::HighlightResourceUsage, id); + } + void HighlightHistory(ResourceId id, const rdcarray &history) + { + return InvokeVoidFunction(&ITimelineBar::HighlightHistory, id, history); + } +}; + +struct IPythonShellInvoker : UIThreadInvoker +{ + IPythonShellInvoker(PythonShell *shell, IPythonShell &obj) : UIThreadInvoker(shell, obj) {} + virtual ~IPythonShellInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + bool CheckUnsavedChanges() { return InvokeRetFunction(&IPythonShell::CheckUnsavedChanges); } + bool LoadScriptFromFilename(rdcstr filename) + { + return InvokeRetFunction(&IPythonShell::LoadScriptFromFilename, filename); + } + void CreateNewScriptEditor(rdcstr name, rdcstr text) + { + return InvokeVoidFunction(&IPythonShell::CreateNewScriptEditor, name, text); + } + rdcstr GetScriptText() { return InvokeRetFunction(&IPythonShell::GetScriptText); } + void RunScript() { return InvokeVoidFunction(&IPythonShell::RunScript); } + void DebugScript() { return InvokeVoidFunction(&IPythonShell::DebugScript); } + void SetExtensionOutputFilter(const rdcstr &extensionName) + { + return InvokeVoidFunction(&IPythonShell::SetExtensionOutputFilter, extensionName); + } + void SetScriptOutputFilter() { return InvokeVoidFunction(&IPythonShell::SetScriptOutputFilter); } + void RemoveOutputFilter() { return InvokeVoidFunction(&IPythonShell::RemoveOutputFilter); } + void ShowOutput() { return InvokeVoidFunction(&IPythonShell::ShowOutput); } + void ShowREPL() { return InvokeVoidFunction(&IPythonShell::ShowREPL); } + void ShowHelp() { return InvokeVoidFunction(&IPythonShell::ShowHelp); } +}; + +struct IResourceInspectorInvoker : UIThreadInvoker +{ + IResourceInspectorInvoker(PythonShell *shell, IResourceInspector &obj) + : UIThreadInvoker(shell, obj) + { + } + virtual ~IResourceInspectorInvoker() {} + + QWidget *Widget() { return m_Obj.Widget(); } + void Inspect(ResourceId id) { return InvokeVoidFunction(&IResourceInspector::Inspect, id); } + ResourceId CurrentResource() + { + return InvokeRetFunction(&IResourceInspector::CurrentResource); + } + void RevealParameter(SDObject *param) + { + return InvokeVoidFunction(&IResourceInspector::RevealParameter, param); + } +}; + +struct CaptureContextInvoker : UIThreadInvoker +{ + ExtensionInvoker *m_Ext; + ReplayControllerInvoker m_ReplayController; + +#define WINDOW_INVOKER(iface) \ + iface##Invoker *m_invoker##iface = NULL; \ + iface *WrapInvoker(iface *i) \ + { \ + if(!m_invoker##iface || &m_invoker##iface->m_Obj != i) \ + { \ + delete m_invoker##iface; \ + m_invoker##iface = new iface##Invoker(m_Shell, *i); \ + } \ + return m_invoker##iface; \ + } + + WINDOW_INVOKER(IMainWindow); + WINDOW_INVOKER(IEventBrowser); + WINDOW_INVOKER(IAPIInspector); + WINDOW_INVOKER(IAnnotationViewer); + WINDOW_INVOKER(ITextureViewer); + WINDOW_INVOKER(IBufferViewer); + WINDOW_INVOKER(IPipelineStateViewer); + WINDOW_INVOKER(ICaptureDialog); + WINDOW_INVOKER(IDebugMessageView); + WINDOW_INVOKER(IDiagnosticLogView); + WINDOW_INVOKER(ICommentView); + WINDOW_INVOKER(IPerformanceCounterViewer); + WINDOW_INVOKER(IStatisticsViewer); + WINDOW_INVOKER(ITimelineBar); + WINDOW_INVOKER(IPythonShell); + WINDOW_INVOKER(IResourceInspector); + + CaptureContextInvoker(PythonShell *shell, ICaptureContext &obj) + : UIThreadInvoker(shell, obj), m_ReplayController(shell, obj) + { + m_Ext = new ExtensionInvoker(shell, obj.Extensions()); + } + virtual ~CaptureContextInvoker() { delete m_Ext; } + // + /////////////////////////////////////////////////////////////////////// + // pass-through functions that don't need the UI thread + /////////////////////////////////////////////////////////////////////// + // + virtual rdcstr TempCaptureFilename(const rdcstr &appname) override + { + return m_Obj.TempCaptureFilename(appname); + } + virtual IExtensionManager &Extensions() override { return *m_Ext; } + virtual IReplayManager &Replay() override { return m_Obj.Replay(); } + virtual bool IsCaptureLoaded() override { return m_Obj.IsCaptureLoaded(); } + virtual bool IsCaptureLocal() override { return m_Obj.IsCaptureLocal(); } + virtual bool IsCaptureTemporary() override { return m_Obj.IsCaptureTemporary(); } + virtual bool IsCaptureLoading() override { return m_Obj.IsCaptureLoading(); } + virtual ResultDetails GetFatalError() override { return m_Obj.GetFatalError(); } + virtual rdcstr GetCaptureFilename() override { return m_Obj.GetCaptureFilename(); } + virtual CaptureModifications GetCaptureModifications() override + { + return m_Obj.GetCaptureModifications(); + } + virtual FrameDescription FrameInfo() override { return m_Obj.FrameInfo(); } + virtual APIProperties APIProps() override { return m_Obj.APIProps(); } + virtual rdcarray TargetShaderEncodings() override + { + return m_Obj.TargetShaderEncodings(); + } + virtual rdcarray CustomShaderEncodings() override + { + return m_Obj.CustomShaderEncodings(); + } + virtual rdcarray CustomShaderSourcePrefixes() override + { + return m_Obj.CustomShaderSourcePrefixes(); + } + virtual uint32_t CurSelectedEvent() override { return m_Obj.CurSelectedEvent(); } + virtual uint32_t CurEvent() override { return m_Obj.CurEvent(); } + virtual const ActionDescription *CurSelectedAction() override + { + return m_Obj.CurSelectedAction(); + } + virtual const ActionDescription *CurAction() override { return m_Obj.CurAction(); } + virtual const ActionDescription *GetFirstAction() override { return m_Obj.GetFirstAction(); } + virtual const ActionDescription *GetLastAction() override { return m_Obj.GetLastAction(); } + virtual const rdcarray &CurRootActions() override + { + return m_Obj.CurRootActions(); + } + virtual const ResourceDescription *GetResource(ResourceId id) const override + { + return m_Obj.GetResource(id); + } + virtual const rdcarray &GetResources() override + { + return m_Obj.GetResources(); + } + virtual rdcstr GetResourceName(ResourceId id) const override { return m_Obj.GetResourceName(id); } + virtual rdcstr GetResourceNameUnsuffixed(ResourceId id) const override + { + return m_Obj.GetResourceNameUnsuffixed(id); + } + virtual bool IsAutogeneratedName(ResourceId id) override { return m_Obj.IsAutogeneratedName(id); } + virtual bool HasResourceCustomName(ResourceId id) override + { + return m_Obj.HasResourceCustomName(id); + } + virtual int32_t ResourceNameCacheID() const override { return m_Obj.ResourceNameCacheID(); } + virtual TextureDescription *GetTexture(ResourceId id) override { return m_Obj.GetTexture(id); } + virtual const rdcarray &GetTextures() override { return m_Obj.GetTextures(); } + virtual BufferDescription *GetBuffer(ResourceId id) override { return m_Obj.GetBuffer(id); } + virtual DescriptorStoreDescription *GetDescriptorStore(ResourceId id) override + { + return m_Obj.GetDescriptorStore(id); + } + virtual const rdcarray &GetBuffers() const override + { + return m_Obj.GetBuffers(); + } + virtual const ActionDescription *GetAction(uint32_t eventId) override + { + return m_Obj.GetAction(eventId); + } + virtual void ClearReplayCache() override { return m_Obj.ClearReplayCache(); } + virtual bool OpenRGPProfile(const rdcstr &filename) override + { + return m_Obj.OpenRGPProfile(filename); + } + virtual IRGPInterop *GetRGPInterop() override { return m_Obj.GetRGPInterop(); } + virtual const SDFile &GetStructuredFile() override { return m_Obj.GetStructuredFile(); } + virtual WindowingSystem CurWindowingSystem() override { return m_Obj.CurWindowingSystem(); } + virtual const rdcarray &DebugMessages() override { return m_Obj.DebugMessages(); } + virtual int32_t UnreadMessageCount() override { return m_Obj.UnreadMessageCount(); } + virtual void MarkMessagesRead() override { return m_Obj.MarkMessagesRead(); } + virtual rdcstr GetNotes(const rdcstr &key) override { return m_Obj.GetNotes(key); } + virtual rdcarray GetBookmarks() override { return m_Obj.GetBookmarks(); } + virtual const D3D11Pipe::State *CurD3D11PipelineState() override + { + return m_Obj.CurD3D11PipelineState(); + } + virtual const D3D12Pipe::State *CurD3D12PipelineState() override + { + return m_Obj.CurD3D12PipelineState(); + } + virtual const GLPipe::State *CurGLPipelineState() override { return m_Obj.CurGLPipelineState(); } + virtual const VKPipe::State *CurVulkanPipelineState() override + { + return m_Obj.CurVulkanPipelineState(); + } + virtual const PipeState &CurPipelineState() override { return m_Obj.CurPipelineState(); } + virtual PersistantConfig &Config() override { return m_Obj.Config(); } + // + /////////////////////////////////////////////////////////////////////// + // functions that invoke onto the UI thread + /////////////////////////////////////////////////////////////////////// + // + virtual void ConnectToRemoteServer(RemoteHost host) override + { + InvokeVoidFunction(&ICaptureContext::ConnectToRemoteServer, host); + } + virtual WindowingData CreateWindowingData(QWidget *window) override + { + return InvokeRetFunction(&ICaptureContext::CreateWindowingData, window); + } + virtual void LoadCapture(const rdcstr &capture, const ReplayOptions &opts, + const rdcstr &origFilename, bool temporary, bool local) override + { + InvokeVoidFunction(&ICaptureContext::LoadCapture, capture, opts, origFilename, temporary, local); + } + virtual bool SaveCaptureTo(const rdcstr &capture) override + { + return InvokeRetFunction(&ICaptureContext::SaveCaptureTo, capture); + } + virtual void RecompressCapture() override + { + InvokeVoidFunction(&ICaptureContext::RecompressCapture); + } + virtual void CloseCapture() override { InvokeVoidFunction(&ICaptureContext::CloseCapture); } + virtual IReplayController *GetBlockingController() override + { + if(!m_Obj.IsCaptureLoaded()) + return NULL; + return &m_ReplayController; + } + virtual bool ImportCapture(const CaptureFileFormat &fmt, const rdcstr &importfile, + const rdcstr &rdcfile) override + { + return InvokeRetFunction(&ICaptureContext::ImportCapture, fmt, importfile, rdcfile); + } + virtual void ExportCapture(const CaptureFileFormat &fmt, const rdcstr &exportfile) override + { + InvokeVoidFunction(&ICaptureContext::ExportCapture, fmt, exportfile); + } + virtual void SetEventID(const rdcarray &exclude, uint32_t selectedEventID, + uint32_t eventId, bool force = false) override + { + InvokeVoidFunction(&ICaptureContext::SetEventID, exclude, selectedEventID, eventId, force); + } + virtual void RefreshStatus() override { InvokeVoidFunction(&ICaptureContext::RefreshStatus); } + virtual bool IsResourceReplaced(ResourceId id) override + { + return InvokeRetFunction(&ICaptureContext::IsResourceReplaced, id); + } + virtual ResourceId GetResourceReplacement(ResourceId id) override + { + return InvokeRetFunction(&ICaptureContext::GetResourceReplacement, id); + } + virtual void RegisterReplacement(ResourceId from, ResourceId to) override + { + InvokeVoidFunction(&ICaptureContext::RegisterReplacement, from, to); + } + virtual void UnregisterReplacement(ResourceId id) override + { + InvokeVoidFunction(&ICaptureContext::UnregisterReplacement, id); + } + virtual void AddCaptureViewer(ICaptureViewer *viewer) override + { + InvokeVoidFunction(&ICaptureContext::AddCaptureViewer, viewer); + } + virtual void RemoveCaptureViewer(ICaptureViewer *viewer) override + { + InvokeVoidFunction(&ICaptureContext::RemoveCaptureViewer, viewer); + } + virtual void AddMessages(const rdcarray &msgs) override + { + InvokeVoidFunction(&ICaptureContext::AddMessages, msgs); + } + virtual void ClearMessages() override { InvokeVoidFunction(&ICaptureContext::ClearMessages); } + virtual void SetResourceCustomName(ResourceId id, const rdcstr &name) override + { + InvokeVoidFunction(&ICaptureContext::SetResourceCustomName, id, name); + } + virtual void SetNotes(const rdcstr &key, const rdcstr &contents) override + { + InvokeVoidFunction(&ICaptureContext::SetNotes, key, contents); + } + + virtual void SetBookmark(const EventBookmark &mark) override + { + InvokeVoidFunction(&ICaptureContext::SetBookmark, mark); + } + virtual void RemoveBookmark(uint32_t EID) override + { + InvokeVoidFunction(&ICaptureContext::RemoveBookmark, EID); + } + virtual void EmbedDependentFiles() override + { + InvokeVoidFunction(&ICaptureContext::EmbedDependentFiles); + } + virtual void RemoveDependentFiles() override + { + InvokeVoidFunction(&ICaptureContext::RemoveDependentFiles); + } + virtual void DelayedCallback(uint32_t milliseconds, std::function callback) override + { + if(!GUIInvoke::onUIThread()) + { + PythonContext *scriptContext = m_Shell->GetScriptContext(); + if(scriptContext) + scriptContext->PausePythonThreading(); + GUIInvoke::call(m_Shell, [this, milliseconds, callback]() { + m_Obj.DelayedCallback(milliseconds, callback); + }); + if(scriptContext) + scriptContext->ResumePythonThreading(); + return; + } + + m_Obj.DelayedCallback(milliseconds, callback); + } + virtual IMainWindow *GetMainWindow() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetMainWindow)); + } + virtual IEventBrowser *GetEventBrowser() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetEventBrowser)); + } + virtual IAPIInspector *GetAPIInspector() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetAPIInspector)); + } + virtual IAnnotationViewer *GetAnnotationViewer() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetAnnotationViewer)); + } + virtual ITextureViewer *GetTextureViewer() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetTextureViewer)); + } + virtual IBufferViewer *GetMeshPreview() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetMeshPreview)); + } + virtual IPipelineStateViewer *GetPipelineViewer() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetPipelineViewer)); + } + virtual ICaptureDialog *GetCaptureDialog() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetCaptureDialog)); + } + virtual IDebugMessageView *GetDebugMessageView() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetDebugMessageView)); + } + virtual IDiagnosticLogView *GetDiagnosticLogView() override + { + return WrapInvoker( + InvokeRetFunction(&ICaptureContext::GetDiagnosticLogView)); + } + virtual ICommentView *GetCommentView() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetCommentView)); + } + virtual IPerformanceCounterViewer *GetPerformanceCounterViewer() override + { + return WrapInvoker(InvokeRetFunction( + &ICaptureContext::GetPerformanceCounterViewer)); + } + virtual IStatisticsViewer *GetStatisticsViewer() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetStatisticsViewer)); + } + virtual ITimelineBar *GetTimelineBar() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetTimelineBar)); + } + virtual IPythonShell *GetPythonShell() override + { + return WrapInvoker(InvokeRetFunction(&ICaptureContext::GetPythonShell)); + } + virtual IResourceInspector *GetResourceInspector() override + { + return WrapInvoker( + InvokeRetFunction(&ICaptureContext::GetResourceInspector)); + } + virtual bool HasEventBrowser() override + { + return InvokeRetFunction(&ICaptureContext::HasEventBrowser); + } + virtual bool HasAPIInspector() override + { + return InvokeRetFunction(&ICaptureContext::HasAPIInspector); + } + virtual bool HasAnnotationViewer() override + { + return InvokeRetFunction(&ICaptureContext::HasAnnotationViewer); + } + virtual bool HasTextureViewer() override + { + return InvokeRetFunction(&ICaptureContext::HasTextureViewer); + } + virtual bool HasPipelineViewer() override + { + return InvokeRetFunction(&ICaptureContext::HasPipelineViewer); + } + virtual bool HasMeshPreview() override + { + return InvokeRetFunction(&ICaptureContext::HasMeshPreview); + } + virtual bool HasCaptureDialog() override + { + return InvokeRetFunction(&ICaptureContext::HasCaptureDialog); + } + virtual bool HasDebugMessageView() override + { + return InvokeRetFunction(&ICaptureContext::HasDebugMessageView); + } + virtual bool HasDiagnosticLogView() override + { + return InvokeRetFunction(&ICaptureContext::HasDiagnosticLogView); + } + virtual bool HasCommentView() override + { + return InvokeRetFunction(&ICaptureContext::HasCommentView); + } + virtual bool HasPerformanceCounterViewer() override + { + return InvokeRetFunction(&ICaptureContext::HasPerformanceCounterViewer); + } + virtual bool HasStatisticsViewer() override + { + return InvokeRetFunction(&ICaptureContext::HasStatisticsViewer); + } + virtual bool HasTimelineBar() override + { + return InvokeRetFunction(&ICaptureContext::HasTimelineBar); + } + virtual bool HasPythonShell() override + { + return InvokeRetFunction(&ICaptureContext::HasPythonShell); + } + virtual bool HasResourceInspector() override + { + return InvokeRetFunction(&ICaptureContext::HasResourceInspector); + } + + virtual void ShowEventBrowser() override + { + InvokeVoidFunction(&ICaptureContext::ShowEventBrowser); + } + virtual void ShowAPIInspector() override + { + InvokeVoidFunction(&ICaptureContext::ShowAPIInspector); + } + virtual void ShowAnnotationViewer() override + { + InvokeVoidFunction(&ICaptureContext::ShowAnnotationViewer); + } + virtual void ShowTextureViewer() override + { + InvokeVoidFunction(&ICaptureContext::ShowTextureViewer); + } + virtual void ShowMeshPreview() override { InvokeVoidFunction(&ICaptureContext::ShowMeshPreview); } + virtual void ShowPipelineViewer() override + { + InvokeVoidFunction(&ICaptureContext::ShowPipelineViewer); + } + virtual void ShowCaptureDialog() override + { + InvokeVoidFunction(&ICaptureContext::ShowCaptureDialog); + } + virtual void ShowDebugMessageView() override + { + InvokeVoidFunction(&ICaptureContext::ShowDebugMessageView); + } + virtual void ShowDiagnosticLogView() override + { + InvokeVoidFunction(&ICaptureContext::ShowDiagnosticLogView); + } + virtual void ShowCommentView() override { InvokeVoidFunction(&ICaptureContext::ShowCommentView); } + virtual void ShowPerformanceCounterViewer() override + { + InvokeVoidFunction(&ICaptureContext::ShowPerformanceCounterViewer); + } + virtual void ShowStatisticsViewer() override + { + InvokeVoidFunction(&ICaptureContext::ShowStatisticsViewer); + } + virtual void ShowTimelineBar() override { InvokeVoidFunction(&ICaptureContext::ShowTimelineBar); } + virtual void ShowPythonShell() override { InvokeVoidFunction(&ICaptureContext::ShowPythonShell); } + virtual void ShowResourceInspector() override + { + InvokeVoidFunction(&ICaptureContext::ShowResourceInspector); + } + virtual IShaderViewer *EditShader(ResourceId id, ShaderStage stage, const rdcstr &entryPoint, + const rdcstrpairs &files, KnownShaderTool knownTool, + ShaderEncoding shaderEncoding, ShaderCompileFlags flags, + IShaderViewer::SaveCallback saveCallback, + IShaderViewer::RevertCallback revertCallback) override + { + return InvokeRetFunction(&ICaptureContext::EditShader, id, stage, entryPoint, + files, knownTool, shaderEncoding, flags, saveCallback, + revertCallback); + } + + virtual IShaderViewer *DebugShader(const ShaderReflection *shader, ResourceId pipeline, + ShaderDebugTrace *trace, const rdcstr &debugContext) override + { + return InvokeRetFunction(&ICaptureContext::DebugShader, shader, pipeline, + trace, debugContext); + } + + virtual IShaderViewer *ViewShader(const ShaderReflection *shader, ResourceId pipeline) override + { + return InvokeRetFunction(&ICaptureContext::ViewShader, shader, pipeline); + } + + virtual IShaderMessageViewer *ViewShaderMessages(ShaderStageMask stages) override + { + return InvokeRetFunction(&ICaptureContext::ViewShaderMessages, stages); + } + + virtual IDescriptorViewer *ViewDescriptorStore(ResourceId id) override + { + return InvokeRetFunction(&ICaptureContext::ViewDescriptorStore, id); + } + virtual IDescriptorViewer *ViewDescriptors(const rdcarray &descriptors, + const rdcarray &samplerDescriptors) override + { + return InvokeRetFunction(&ICaptureContext::ViewDescriptors, descriptors, + samplerDescriptors); + } + + virtual IBufferViewer *ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, + const rdcstr &format = "") override + { + return InvokeRetFunction(&ICaptureContext::ViewBuffer, byteOffset, byteSize, + id, format); + } + + virtual IBufferViewer *ViewTextureAsBuffer(ResourceId id, const Subresource &sub, + const rdcstr &format = "") override + { + return InvokeRetFunction(&ICaptureContext::ViewTextureAsBuffer, id, sub, format); + } + + virtual IBufferViewer *ViewConstantBuffer(ShaderStage stage, uint32_t slot, uint32_t idx) override + { + return InvokeRetFunction(&ICaptureContext::ViewConstantBuffer, stage, slot, idx); + } + + virtual IPixelHistoryView *ViewPixelHistory(ResourceId texID, uint32_t x, uint32_t y, + uint32_t view, const TextureDisplay &display) override + { + return InvokeRetFunction(&ICaptureContext::ViewPixelHistory, texID, x, y, + view, display); + } + + virtual QWidget *CreateBuiltinWindow(const rdcstr &objectName) override + { + return InvokeRetFunction(&ICaptureContext::CreateBuiltinWindow, objectName); + } + + virtual void BuiltinWindowClosed(QWidget *window) override + { + InvokeVoidFunction(&ICaptureContext::BuiltinWindowClosed, window); + } + + virtual void RaiseDockWindow(QWidget *dockWindow) override + { + InvokeVoidFunction(&ICaptureContext::RaiseDockWindow, dockWindow); + } + + virtual void AddDockWindow(QWidget *newWindow, DockReference ref, QWidget *refWindow, + float percentage = 0.5f) override + { + InvokeVoidFunction(&ICaptureContext::AddDockWindow, newWindow, ref, refWindow, percentage); + } +}; + +ICaptureContext *MakeCaptureContextInvoker(PythonShell *shell, ICaptureContext &ctx) +{ + return new CaptureContextInvoker(shell, ctx); +} + +void FreeCaptureContextInvoker(ICaptureContext *ctx) +{ + CaptureContextInvoker *invoker = (CaptureContextInvoker *)ctx; + delete invoker; +} diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp index 7723c13e7..b4ffdf636 100644 --- a/qrenderdoc/Windows/PythonShell.cpp +++ b/qrenderdoc/Windows/PythonShell.cpp @@ -48,1263 +48,6 @@ enum FirstExtensionOutputFilter, }; -// a forwarder that invokes onto the UI thread wherever necessary. -// Note this does NOT make CaptureContext thread safe. We just invoke for any potentially UI -// operations. All invokes are blocking, so there can't be any times when the UI thread waits -// on the python thread. -template -struct UIThreadInvoker : Obj -{ - UIThreadInvoker(PythonShell *sh, Obj &o) : m_Shell(sh), m_Obj(o) {} - PythonShell *m_Shell; - Obj &m_Obj; - - template - void InvokeVoidFunction(F ptr, paramTypes... params) - { - if(!GUIInvoke::onUIThread()) - { - PythonContext *scriptContext = m_Shell->GetScriptContext(); - if(scriptContext) - scriptContext->PausePythonThreading(); - GUIInvoke::blockcall(m_Shell, [this, ptr, params...]() { (m_Obj.*ptr)(params...); }); - if(scriptContext) - scriptContext->ResumePythonThreading(); - return; - } - - (m_Obj.*ptr)(params...); - } - - template - R InvokeRetFunction(F ptr, paramTypes... params) - { - if(!GUIInvoke::onUIThread()) - { - R ret; - PythonContext *scriptContext = m_Shell->GetScriptContext(); - if(scriptContext) - scriptContext->PausePythonThreading(); - GUIInvoke::blockcall(m_Shell, - [this, &ret, ptr, params...]() { ret = (m_Obj.*ptr)(params...); }); - if(scriptContext) - scriptContext->ResumePythonThreading(); - return ret; - } - - return (m_Obj.*ptr)(params...); - } -}; - -struct MiniQtInvoker : UIThreadInvoker -{ - MiniQtInvoker(PythonShell *shell, IMiniQtHelper &obj) : UIThreadInvoker(shell, obj) {} - virtual ~MiniQtInvoker() {} - void InvokeOntoUIThread(std::function callback) - { - // this function is already thread safe since it's invoking, so just call it directly - m_Obj.InvokeOntoUIThread(callback); - } - - /////////////////////////////////////////////////////////////////////// - // all functions invoke onto the UI thread since they deal with widgets! - /////////////////////////////////////////////////////////////////////// - - QWidget *CreateToplevelWidget(const rdcstr &windowTitle, WidgetCallback closed) - { - return InvokeRetFunction(&IMiniQtHelper::CreateToplevelWidget, windowTitle, closed); - } - void CloseToplevelWidget(QWidget *widget) - { - InvokeVoidFunction(&IMiniQtHelper::CloseToplevelWidget, widget); - } - - // widget hierarchy - - void SetWidgetName(QWidget *widget, const rdcstr &name) - { - InvokeVoidFunction(&IMiniQtHelper::SetWidgetName, widget, name); - } - rdcstr GetWidgetName(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::GetWidgetName, widget); - } - rdcstr GetWidgetType(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::GetWidgetType, widget); - } - QWidget *FindChildByName(QWidget *parent, const rdcstr &name) - { - return InvokeRetFunction(&IMiniQtHelper::FindChildByName, parent, name); - } - QWidget *GetParent(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::GetParent, widget); - } - int32_t GetNumChildren(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::GetNumChildren, widget); - } - QWidget *GetChild(QWidget *parent, int32_t index) - { - return InvokeRetFunction(&IMiniQtHelper::GetChild, parent, index); - } - void DestroyWidget(QWidget *widget) { InvokeVoidFunction(&IMiniQtHelper::DestroyWidget, widget); } - // dialogs - - bool ShowWidgetAsDialog(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::ShowWidgetAsDialog, widget); - } - void CloseCurrentDialog(bool success) - { - InvokeVoidFunction(&IMiniQtHelper::CloseCurrentDialog, success); - } - - // layout functions - - QWidget *CreateHorizontalContainer() - { - return InvokeRetFunction(&IMiniQtHelper::CreateHorizontalContainer); - } - QWidget *CreateVerticalContainer() - { - return InvokeRetFunction(&IMiniQtHelper::CreateVerticalContainer); - } - QWidget *CreateGridContainer() - { - return InvokeRetFunction(&IMiniQtHelper::CreateGridContainer); - } - QWidget *CreateSpacer(bool horizontal) - { - return InvokeRetFunction(&IMiniQtHelper::CreateSpacer, horizontal); - } - void ClearContainedWidgets(QWidget *parent) - { - InvokeVoidFunction(&IMiniQtHelper::ClearContainedWidgets, parent); - } - void AddGridWidget(QWidget *parent, int32_t row, int32_t column, QWidget *child, int32_t rowSpan, - int32_t columnSpan) - { - InvokeVoidFunction(&IMiniQtHelper::AddGridWidget, parent, row, column, child, rowSpan, - columnSpan); - } - void AddWidget(QWidget *parent, QWidget *child) - { - InvokeVoidFunction(&IMiniQtHelper::AddWidget, parent, child); - } - void InsertWidget(QWidget *parent, int32_t index, QWidget *child) - { - InvokeVoidFunction(&IMiniQtHelper::InsertWidget, parent, index, child); - } - - // widget manipulation - - void SetWidgetText(QWidget *widget, const rdcstr &text) - { - InvokeVoidFunction(&IMiniQtHelper::SetWidgetText, widget, text); - } - rdcstr GetWidgetText(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::GetWidgetText, widget); - } - - void SetWidgetFont(QWidget *widget, const rdcstr &font, int32_t fontSize, bool bold, bool italic) - { - InvokeVoidFunction(&IMiniQtHelper::SetWidgetFont, widget, font, fontSize, bold, italic); - } - - void SetWidgetEnabled(QWidget *widget, bool enabled) - { - InvokeVoidFunction(&IMiniQtHelper::SetWidgetEnabled, widget, enabled); - } - bool IsWidgetEnabled(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::IsWidgetEnabled, widget); - } - void SetWidgetVisible(QWidget *widget, bool visible) - { - InvokeVoidFunction(&IMiniQtHelper::SetWidgetVisible, widget, visible); - } - bool IsWidgetVisible(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::IsWidgetVisible, widget); - } - - // specific widgets - - QWidget *CreateGroupBox(bool collapsible) - { - return InvokeRetFunction(&IMiniQtHelper::CreateGroupBox, collapsible); - } - - QWidget *CreateButton(WidgetCallback pressed) - { - return InvokeRetFunction(&IMiniQtHelper::CreateButton, pressed); - } - - QWidget *CreateLabel() { return InvokeRetFunction(&IMiniQtHelper::CreateLabel); } - void SetLabelImage(QWidget *widget, const bytebuf &data, int32_t width, int32_t height, bool alpha) - { - InvokeVoidFunction(&IMiniQtHelper::SetLabelImage, widget, data, width, height, alpha); - } - QWidget *CreateOutputRenderingWidget() - { - return InvokeRetFunction(&IMiniQtHelper::CreateOutputRenderingWidget); - } - WindowingData GetWidgetWindowingData(QWidget *widget) - { - return InvokeRetFunction(&IMiniQtHelper::GetWidgetWindowingData, widget); - } - - void SetWidgetReplayOutput(QWidget *widget, IReplayOutput *output) - { - InvokeVoidFunction(&IMiniQtHelper::SetWidgetReplayOutput, widget, output); - } - - void SetWidgetBackgroundColor(QWidget *widget, float red, float green, float blue) - { - InvokeVoidFunction(&IMiniQtHelper::SetWidgetBackgroundColor, widget, red, green, blue); - } - QWidget *CreateCheckbox(WidgetCallback changed) - { - return InvokeRetFunction(&IMiniQtHelper::CreateCheckbox, changed); - } - QWidget *CreateRadiobox(WidgetCallback changed) - { - return InvokeRetFunction(&IMiniQtHelper::CreateRadiobox, changed); - } - - void SetWidgetChecked(QWidget *checkableWidget, bool checked) - { - InvokeVoidFunction(&IMiniQtHelper::SetWidgetChecked, checkableWidget, checked); - } - bool IsWidgetChecked(QWidget *checkableWidget) - { - return InvokeRetFunction(&IMiniQtHelper::IsWidgetChecked, checkableWidget); - } - - QWidget *CreateSpinbox(int32_t decimalPlaces, double step) - { - return InvokeRetFunction(&IMiniQtHelper::CreateSpinbox, decimalPlaces, step); - } - - void SetSpinboxBounds(QWidget *spinbox, double minVal, double maxVal) - { - InvokeVoidFunction(&IMiniQtHelper::SetSpinboxBounds, spinbox, minVal, maxVal); - } - void SetSpinboxValue(QWidget *spinbox, double value) - { - InvokeVoidFunction(&IMiniQtHelper::SetSpinboxValue, spinbox, value); - } - double GetSpinboxValue(QWidget *spinbox) - { - return InvokeRetFunction(&IMiniQtHelper::GetSpinboxValue, spinbox); - } - - QWidget *CreateTextBox(bool singleLine, WidgetCallback changed) - { - return InvokeRetFunction(&IMiniQtHelper::CreateTextBox, singleLine, changed); - } - - QWidget *CreateComboBox(bool editable, WidgetCallback changed) - { - return InvokeRetFunction(&IMiniQtHelper::CreateComboBox, editable, changed); - } - - void SetComboOptions(QWidget *combo, const rdcarray &options) - { - InvokeVoidFunction(&IMiniQtHelper::SetComboOptions, combo, options); - } - - size_t GetComboCount(QWidget *combo) - { - return InvokeRetFunction(&IMiniQtHelper::GetComboCount, combo); - } - - void SelectComboOption(QWidget *combo, const rdcstr &option) - { - InvokeVoidFunction(&IMiniQtHelper::SelectComboOption, combo, option); - } - - QWidget *CreateProgressBar(bool horizontal) - { - return InvokeRetFunction(&IMiniQtHelper::CreateProgressBar, horizontal); - } - - void ResetProgressBar(QWidget *pbar) - { - InvokeVoidFunction(&IMiniQtHelper::ResetProgressBar, pbar); - } - - void SetProgressBarValue(QWidget *pbar, int32_t value) - { - InvokeVoidFunction(&IMiniQtHelper::SetProgressBarValue, pbar, value); - } - - void UpdateProgressBarValue(QWidget *pbar, int32_t delta) - { - InvokeVoidFunction(&IMiniQtHelper::UpdateProgressBarValue, pbar, delta); - } - - int32_t GetProgressBarValue(QWidget *pbar) - { - return InvokeRetFunction(&IMiniQtHelper::GetProgressBarValue, pbar); - } - - void SetProgressBarRange(QWidget *pbar, int32_t minimum, int32_t maximum) - { - InvokeVoidFunction(&IMiniQtHelper::SetProgressBarRange, pbar, minimum, maximum); - } - - int32_t GetProgressBarMinimum(QWidget *pbar) - { - return InvokeRetFunction(&IMiniQtHelper::GetProgressBarMinimum, pbar); - } - - int32_t GetProgressBarMaximum(QWidget *pbar) - { - return InvokeRetFunction(&IMiniQtHelper::GetProgressBarMaximum, pbar); - } -}; - -struct ExtensionInvoker : UIThreadInvoker -{ - MiniQtInvoker *m_MiniQt; - ExtensionInvoker(PythonShell *shell, IExtensionManager &obj) : UIThreadInvoker(shell, obj) - { - m_MiniQt = new MiniQtInvoker(shell, obj.GetMiniQtHelper()); - } - virtual ~ExtensionInvoker() { delete m_MiniQt; } - // - /////////////////////////////////////////////////////////////////////// - // pass-through functions that don't need the UI thread - /////////////////////////////////////////////////////////////////////// - // - rdcarray GetInstalledExtensions() { return m_Obj.GetInstalledExtensions(); } - rdcarray GetLoadedExtensions() { return m_Obj.GetLoadedExtensions(); } - bool IsExtensionLoaded(rdcstr name) { return m_Obj.IsExtensionLoaded(name); } - rdcstr LoadExtension(rdcstr name) { return m_Obj.LoadExtension(name); } - bool IsPythonDebuggerConnected() { return m_Obj.IsPythonDebuggerConnected(); } - IMiniQtHelper &GetMiniQtHelper() { return *m_MiniQt; } - // - /////////////////////////////////////////////////////////////////////// - // functions that invoke onto the UI thread - /////////////////////////////////////////////////////////////////////// - // - void RegisterWindowMenu(WindowMenu base, const rdcarray &submenus, - ExtensionCallback callback) - { - InvokeVoidFunction(&IExtensionManager::RegisterWindowMenu, base, submenus, callback); - } - - void RegisterPanelMenu(PanelMenu base, const rdcarray &submenus, ExtensionCallback callback) - { - InvokeVoidFunction(&IExtensionManager::RegisterPanelMenu, base, submenus, callback); - } - - void RegisterContextMenu(ContextMenu base, const rdcarray &submenus, - ExtensionCallback callback) - { - InvokeVoidFunction(&IExtensionManager::RegisterContextMenu, base, submenus, callback); - } - - void MessageDialog(const rdcstr &text, const rdcstr &title) - { - InvokeVoidFunction(&IExtensionManager::MessageDialog, text, title); - } - - void ErrorDialog(const rdcstr &text, const rdcstr &title) - { - InvokeVoidFunction(&IExtensionManager::ErrorDialog, text, title); - } - - DialogButton QuestionDialog(const rdcstr &text, const rdcarray &options, - const rdcstr &title) - { - return InvokeRetFunction(&IExtensionManager::QuestionDialog, text, options, title); - } - - rdcstr OpenFileName(const rdcstr &caption, const rdcstr &dir, const rdcstr &filter) - { - return InvokeRetFunction(&IExtensionManager::OpenFileName, caption, dir, filter); - } - - rdcstr OpenDirectoryName(const rdcstr &caption, const rdcstr &dir) - { - return InvokeRetFunction(&IExtensionManager::OpenDirectoryName, caption, dir); - } - - rdcstr SaveFileName(const rdcstr &caption, const rdcstr &dir, const rdcstr &filter) - { - return InvokeRetFunction(&IExtensionManager::SaveFileName, caption, dir, filter); - } - - void MenuDisplaying(ContextMenu contextMenu, QMenu *menu, const ExtensionCallbackData &data) - { - InvokeVoidFunction( - (void(IExtensionManager::*)(ContextMenu, QMenu *, const ExtensionCallbackData &)) & - IExtensionManager::MenuDisplaying, - contextMenu, menu, data); - } - void MenuDisplaying(PanelMenu panelMenu, QMenu *menu, QWidget *extensionButton, - const ExtensionCallbackData &data) - { - InvokeVoidFunction( - (void(IExtensionManager::*)(PanelMenu, QMenu *, QWidget *, const ExtensionCallbackData &)) & - IExtensionManager::MenuDisplaying, - panelMenu, menu, extensionButton, data); - } -}; - -struct ReplayControllerInvoker : IReplayController -{ - ReplayControllerInvoker(PythonShell *shell, ICaptureContext &ctx) : m_Shell(shell), m_Ctx(ctx) {} - PythonShell *m_Shell; - ICaptureContext &m_Ctx; - - template - void InvokeVoidFunction(F ptr, paramTypes... params) - { - PythonContext *scriptContext = m_Shell->GetScriptContext(); - if(scriptContext) - scriptContext->PausePythonThreading(); - m_Ctx.Replay().BlockInvoke( - [this, ptr, params...](IReplayController *replay) { (replay->*ptr)(params...); }); - if(scriptContext) - scriptContext->ResumePythonThreading(); - } - - template - R InvokeRetFunction(F ptr, paramTypes... params) - { - R ret = R(); - PythonContext *scriptContext = m_Shell->GetScriptContext(); - if(scriptContext) - scriptContext->PausePythonThreading(); - m_Ctx.Replay().BlockInvoke([this, &ret, ptr, params...](IReplayController *replay) { - ret = (replay->*ptr)(params...); - }); - if(scriptContext) - scriptContext->ResumePythonThreading(); - return ret; - } - - template - R &InvokeRetRefFunction(F ptr, paramTypes... params) - { - R *ret = NULL; - PythonContext *scriptContext = m_Shell->GetScriptContext(); - if(scriptContext) - scriptContext->PausePythonThreading(); - m_Ctx.Replay().BlockInvoke([this, &ret, ptr, params...](IReplayController *replay) { - ret = &(replay->*ptr)(params...); - }); - if(scriptContext) - scriptContext->ResumePythonThreading(); - return *ret; - } - - APIProperties GetAPIProperties() - { - return InvokeRetFunction(&IReplayController::GetAPIProperties); - } - - rdcarray GetSupportedWindowSystems() - { - return InvokeRetFunction>(&IReplayController::GetSupportedWindowSystems); - } - - IReplayOutput *CreateOutput(WindowingData window, ReplayOutputType type) - { - return InvokeRetFunction(&IReplayController::CreateOutput, window, type); - } - - void Shutdown() {} - - void ReplayLoop(WindowingData window, ResourceId texid) {} - - rdcstr CreateRGPProfile(WindowingData window) - { - return InvokeRetFunction(&IReplayController::CreateRGPProfile, window); - } - - void CancelReplayLoop() {} - - void FileChanged() {} - - void SetFrameEvent(uint32_t eventId, bool force) {} - - const D3D11Pipe::State *GetD3D11PipelineState() - { - return InvokeRetFunction(&IReplayController::GetD3D11PipelineState); - } - - const D3D12Pipe::State *GetD3D12PipelineState() - { - return InvokeRetFunction(&IReplayController::GetD3D12PipelineState); - } - - const GLPipe::State *GetGLPipelineState() - { - return InvokeRetFunction(&IReplayController::GetGLPipelineState); - } - - const VKPipe::State *GetVulkanPipelineState() - { - return InvokeRetFunction(&IReplayController::GetVulkanPipelineState); - } - - const PipeState &GetPipelineState() - { - return InvokeRetRefFunction(&IReplayController::GetPipelineState); - } - - rdcarray GetDescriptors(ResourceId descriptorStore, - const rdcarray &ranges) - { - return InvokeRetFunction>(&IReplayController::GetDescriptors, - descriptorStore, ranges); - } - - rdcarray GetSamplerDescriptors(ResourceId descriptorStore, - const rdcarray &ranges) - { - return InvokeRetFunction>(&IReplayController::GetSamplerDescriptors, - descriptorStore, ranges); - } - - const rdcarray &GetDescriptorAccess() - { - return InvokeRetRefFunction>( - &IReplayController::GetDescriptorAccess); - } - - rdcarray GetDescriptorLocations(ResourceId descriptorStore, - const rdcarray &ranges) - { - return InvokeRetFunction>( - &IReplayController::GetDescriptorLocations, descriptorStore, ranges); - } - - rdcarray GetDisassemblyTargets(bool withPipeline) - { - return InvokeRetFunction>(&IReplayController::GetDisassemblyTargets, - withPipeline); - } - - rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target) - { - return InvokeRetFunction(&IReplayController::DisassembleShader, pipeline, refl, target); - } - - void SetCustomShaderIncludes(const rdcarray &directories) {} - - rdcpair BuildCustomShader(const rdcstr &entry, ShaderEncoding sourceEncoding, - bytebuf source, - const ShaderCompileFlags &compileFlags, - ShaderStage type) - { - return InvokeRetFunction>( - &IReplayController::BuildCustomShader, entry, sourceEncoding, source, compileFlags, type); - } - - void FreeCustomShader(ResourceId id) {} - - rdcpair BuildTargetShader(const rdcstr &entry, ShaderEncoding sourceEncoding, - bytebuf source, - const ShaderCompileFlags &compileFlags, - ShaderStage type) - { - return InvokeRetFunction>( - &IReplayController::BuildTargetShader, entry, sourceEncoding, source, compileFlags, type); - } - - rdcarray GetTargetShaderEncodings() - { - return InvokeRetFunction>(&IReplayController::GetTargetShaderEncodings); - } - - rdcarray GetCustomShaderEncodings() - { - return InvokeRetFunction>(&IReplayController::GetCustomShaderEncodings); - } - - rdcarray GetCustomShaderSourcePrefixes() - { - return InvokeRetFunction>( - &IReplayController::GetCustomShaderSourcePrefixes); - } - - void ReplaceResource(ResourceId original, ResourceId replacement) {} - - void ClearReplayCache() {} - - void ReloadShaderDebugInformation() {} - - void RemoveReplacement(ResourceId id) {} - - void FreeTargetResource(ResourceId id) {} - - FrameDescription GetFrameInfo() - { - return InvokeRetFunction(&IReplayController::GetFrameInfo); - } - - const SDFile &GetStructuredFile() - { - return InvokeRetRefFunction(&IReplayController::GetStructuredFile); - } - - void AddFakeMarkers() {} - - const rdcarray &GetRootActions() - { - return InvokeRetRefFunction>(&IReplayController::GetRootActions); - } - - rdcarray FetchCounters(const rdcarray &counters) - { - return InvokeRetFunction>(&IReplayController::FetchCounters, counters); - } - - rdcarray EnumerateCounters() - { - return InvokeRetFunction>(&IReplayController::EnumerateCounters); - } - - CounterDescription DescribeCounter(GPUCounter counter) - { - return InvokeRetFunction(&IReplayController::DescribeCounter, counter); - } - - const rdcarray &GetResources() - { - return InvokeRetRefFunction>(&IReplayController::GetResources); - } - - const rdcarray &GetTextures() - { - return InvokeRetRefFunction>(&IReplayController::GetTextures); - } - - const rdcarray &GetBuffers() - { - return InvokeRetRefFunction>(&IReplayController::GetBuffers); - } - - const rdcarray &GetDescriptorStores() - { - return InvokeRetRefFunction>( - &IReplayController::GetDescriptorStores); - } - - rdcarray GetDebugMessages() - { - return InvokeRetFunction>(&IReplayController::GetDebugMessages); - } - - ResultDetails GetFatalErrorStatus() - { - return InvokeRetFunction(&IReplayController::GetFatalErrorStatus); - } - - rdcarray GetShaderEntryPoints(ResourceId shader) - { - return InvokeRetFunction>(&IReplayController::GetShaderEntryPoints, - shader); - } - - const ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry) - { - return InvokeRetFunction(&IReplayController::GetShader, pipeline, - shader, entry); - } - - PixelValue PickPixel(ResourceId textureId, uint32_t x, uint32_t y, const Subresource &sub, - CompType typeCast) - { - return InvokeRetFunction(&IReplayController::PickPixel, textureId, x, y, sub, - typeCast); - } - - rdcpair GetMinMax(ResourceId textureId, const Subresource &sub, - CompType typeCast) - { - return InvokeRetFunction>(&IReplayController::GetMinMax, - textureId, sub, typeCast); - } - - rdcarray GetHistogram(ResourceId textureId, const Subresource &sub, CompType typeCast, - float minval, float maxval, const rdcfixedarray &channels) - { - return InvokeRetFunction>(&IReplayController::GetHistogram, textureId, sub, - typeCast, minval, maxval, channels); - } - - rdcarray PixelHistory(ResourceId texture, uint32_t x, uint32_t y, - const Subresource &sub, CompType typeCast) - { - return InvokeRetFunction>(&IReplayController::PixelHistory, texture, - x, y, sub, typeCast); - } - - ShaderDebugTrace *DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t view) - { - return InvokeRetFunction(&IReplayController::DebugVertex, vertid, instid, - idx, view); - } - - ShaderDebugTrace *DebugPixel(uint32_t x, uint32_t y, const DebugPixelInputs &inputs) - { - return InvokeRetFunction(&IReplayController::DebugPixel, x, y, inputs); - } - - ShaderDebugTrace *DebugThread(const rdcfixedarray &groupid, - const rdcfixedarray &threadid) - { - return InvokeRetFunction(&IReplayController::DebugThread, groupid, threadid); - } - - ShaderDebugTrace *DebugMeshThread(const rdcfixedarray &groupid, - const rdcfixedarray &threadid) - { - return InvokeRetFunction(&IReplayController::DebugMeshThread, groupid, - threadid); - } - - rdcarray ContinueDebug(ShaderDebugger *debugger) - { - return InvokeRetFunction>(&IReplayController::ContinueDebug, debugger); - } - - void FreeTrace(ShaderDebugTrace *trace) - { - return InvokeVoidFunction(&IReplayController::FreeTrace, trace); - } - - rdcarray GetUsage(ResourceId id) - { - return InvokeRetFunction>(&IReplayController::GetUsage, id); - } - - rdcarray GetCBufferVariableContents(ResourceId pipeline, ResourceId shader, - ShaderStage stage, const rdcstr &entryPoint, - uint32_t cbufslot, ResourceId buffer, - uint64_t offset, uint64_t length) - { - return InvokeRetFunction>( - &IReplayController::GetCBufferVariableContents, pipeline, shader, stage, entryPoint, - cbufslot, buffer, offset, length); - } - - ResultDetails SaveTexture(const TextureSave &saveData, const rdcstr &path) - { - return InvokeRetFunction(&IReplayController::SaveTexture, saveData, path); - } - - MeshFormat GetPostVSData(uint32_t instance, uint32_t view, MeshDataStage stage) - { - return InvokeRetFunction(&IReplayController::GetPostVSData, instance, view, stage); - } - - bytebuf GetBufferData(ResourceId buff, uint64_t offset, uint64_t len) - { - return InvokeRetFunction(&IReplayController::GetBufferData, buff, offset, len); - } - - bytebuf GetTextureData(ResourceId tex, const Subresource &sub) - { - return InvokeRetFunction(&IReplayController::GetTextureData, tex, sub); - } -}; - -struct CaptureContextInvoker : UIThreadInvoker -{ - ExtensionInvoker *m_Ext; - ReplayControllerInvoker m_ReplayController; - CaptureContextInvoker(PythonShell *shell, ICaptureContext &obj) - : UIThreadInvoker(shell, obj), m_ReplayController(shell, obj) - { - m_Ext = new ExtensionInvoker(shell, obj.Extensions()); - } - virtual ~CaptureContextInvoker() { delete m_Ext; } - // - /////////////////////////////////////////////////////////////////////// - // pass-through functions that don't need the UI thread - /////////////////////////////////////////////////////////////////////// - // - virtual rdcstr TempCaptureFilename(const rdcstr &appname) override - { - return m_Obj.TempCaptureFilename(appname); - } - virtual IExtensionManager &Extensions() override { return *m_Ext; } - virtual IReplayManager &Replay() override { return m_Obj.Replay(); } - virtual bool IsCaptureLoaded() override { return m_Obj.IsCaptureLoaded(); } - virtual bool IsCaptureLocal() override { return m_Obj.IsCaptureLocal(); } - virtual bool IsCaptureTemporary() override { return m_Obj.IsCaptureTemporary(); } - virtual bool IsCaptureLoading() override { return m_Obj.IsCaptureLoading(); } - virtual ResultDetails GetFatalError() override { return m_Obj.GetFatalError(); } - virtual rdcstr GetCaptureFilename() override { return m_Obj.GetCaptureFilename(); } - virtual CaptureModifications GetCaptureModifications() override - { - return m_Obj.GetCaptureModifications(); - } - virtual FrameDescription FrameInfo() override { return m_Obj.FrameInfo(); } - virtual APIProperties APIProps() override { return m_Obj.APIProps(); } - virtual rdcarray TargetShaderEncodings() override - { - return m_Obj.TargetShaderEncodings(); - } - virtual rdcarray CustomShaderEncodings() override - { - return m_Obj.CustomShaderEncodings(); - } - virtual rdcarray CustomShaderSourcePrefixes() override - { - return m_Obj.CustomShaderSourcePrefixes(); - } - virtual uint32_t CurSelectedEvent() override { return m_Obj.CurSelectedEvent(); } - virtual uint32_t CurEvent() override { return m_Obj.CurEvent(); } - virtual const ActionDescription *CurSelectedAction() override - { - return m_Obj.CurSelectedAction(); - } - virtual const ActionDescription *CurAction() override { return m_Obj.CurAction(); } - virtual const ActionDescription *GetFirstAction() override { return m_Obj.GetFirstAction(); } - virtual const ActionDescription *GetLastAction() override { return m_Obj.GetLastAction(); } - virtual const rdcarray &CurRootActions() override - { - return m_Obj.CurRootActions(); - } - virtual const ResourceDescription *GetResource(ResourceId id) const override - { - return m_Obj.GetResource(id); - } - virtual const rdcarray &GetResources() override - { - return m_Obj.GetResources(); - } - virtual rdcstr GetResourceName(ResourceId id) const override { return m_Obj.GetResourceName(id); } - virtual rdcstr GetResourceNameUnsuffixed(ResourceId id) const override - { - return m_Obj.GetResourceNameUnsuffixed(id); - } - virtual bool IsAutogeneratedName(ResourceId id) override { return m_Obj.IsAutogeneratedName(id); } - virtual bool HasResourceCustomName(ResourceId id) override - { - return m_Obj.HasResourceCustomName(id); - } - virtual int32_t ResourceNameCacheID() const override { return m_Obj.ResourceNameCacheID(); } - virtual TextureDescription *GetTexture(ResourceId id) override { return m_Obj.GetTexture(id); } - virtual const rdcarray &GetTextures() override { return m_Obj.GetTextures(); } - virtual BufferDescription *GetBuffer(ResourceId id) override { return m_Obj.GetBuffer(id); } - virtual DescriptorStoreDescription *GetDescriptorStore(ResourceId id) override - { - return m_Obj.GetDescriptorStore(id); - } - virtual const rdcarray &GetBuffers() const override - { - return m_Obj.GetBuffers(); - } - virtual const ActionDescription *GetAction(uint32_t eventId) override - { - return m_Obj.GetAction(eventId); - } - virtual void ClearReplayCache() override { return m_Obj.ClearReplayCache(); } - virtual bool OpenRGPProfile(const rdcstr &filename) override - { - return m_Obj.OpenRGPProfile(filename); - } - virtual IRGPInterop *GetRGPInterop() override { return m_Obj.GetRGPInterop(); } - virtual const SDFile &GetStructuredFile() override { return m_Obj.GetStructuredFile(); } - virtual WindowingSystem CurWindowingSystem() override { return m_Obj.CurWindowingSystem(); } - virtual const rdcarray &DebugMessages() override { return m_Obj.DebugMessages(); } - virtual int32_t UnreadMessageCount() override { return m_Obj.UnreadMessageCount(); } - virtual void MarkMessagesRead() override { return m_Obj.MarkMessagesRead(); } - virtual rdcstr GetNotes(const rdcstr &key) override { return m_Obj.GetNotes(key); } - virtual rdcarray GetBookmarks() override { return m_Obj.GetBookmarks(); } - virtual const D3D11Pipe::State *CurD3D11PipelineState() override - { - return m_Obj.CurD3D11PipelineState(); - } - virtual const D3D12Pipe::State *CurD3D12PipelineState() override - { - return m_Obj.CurD3D12PipelineState(); - } - virtual const GLPipe::State *CurGLPipelineState() override { return m_Obj.CurGLPipelineState(); } - virtual const VKPipe::State *CurVulkanPipelineState() override - { - return m_Obj.CurVulkanPipelineState(); - } - virtual const PipeState &CurPipelineState() override { return m_Obj.CurPipelineState(); } - virtual PersistantConfig &Config() override { return m_Obj.Config(); } - // - /////////////////////////////////////////////////////////////////////// - // functions that invoke onto the UI thread - /////////////////////////////////////////////////////////////////////// - // - virtual void ConnectToRemoteServer(RemoteHost host) override - { - InvokeVoidFunction(&ICaptureContext::ConnectToRemoteServer, host); - } - virtual WindowingData CreateWindowingData(QWidget *window) override - { - return InvokeRetFunction(&ICaptureContext::CreateWindowingData, window); - } - virtual void LoadCapture(const rdcstr &capture, const ReplayOptions &opts, - const rdcstr &origFilename, bool temporary, bool local) override - { - InvokeVoidFunction(&ICaptureContext::LoadCapture, capture, opts, origFilename, temporary, local); - } - virtual bool SaveCaptureTo(const rdcstr &capture) override - { - return InvokeRetFunction(&ICaptureContext::SaveCaptureTo, capture); - } - virtual void RecompressCapture() override - { - InvokeVoidFunction(&ICaptureContext::RecompressCapture); - } - virtual void CloseCapture() override { InvokeVoidFunction(&ICaptureContext::CloseCapture); } - virtual IReplayController *GetBlockingController() override - { - if(!m_Obj.IsCaptureLoaded()) - return NULL; - return &m_ReplayController; - } - virtual bool ImportCapture(const CaptureFileFormat &fmt, const rdcstr &importfile, - const rdcstr &rdcfile) override - { - return InvokeRetFunction(&ICaptureContext::ImportCapture, fmt, importfile, rdcfile); - } - virtual void ExportCapture(const CaptureFileFormat &fmt, const rdcstr &exportfile) override - { - InvokeVoidFunction(&ICaptureContext::ExportCapture, fmt, exportfile); - } - virtual void SetEventID(const rdcarray &exclude, uint32_t selectedEventID, - uint32_t eventId, bool force = false) override - { - InvokeVoidFunction(&ICaptureContext::SetEventID, exclude, selectedEventID, eventId, force); - } - virtual void RefreshStatus() override { InvokeVoidFunction(&ICaptureContext::RefreshStatus); } - virtual bool IsResourceReplaced(ResourceId id) override - { - return InvokeRetFunction(&ICaptureContext::IsResourceReplaced, id); - } - virtual ResourceId GetResourceReplacement(ResourceId id) override - { - return InvokeRetFunction(&ICaptureContext::GetResourceReplacement, id); - } - virtual void RegisterReplacement(ResourceId from, ResourceId to) override - { - InvokeVoidFunction(&ICaptureContext::RegisterReplacement, from, to); - } - virtual void UnregisterReplacement(ResourceId id) override - { - InvokeVoidFunction(&ICaptureContext::UnregisterReplacement, id); - } - virtual void AddCaptureViewer(ICaptureViewer *viewer) override - { - InvokeVoidFunction(&ICaptureContext::AddCaptureViewer, viewer); - } - virtual void RemoveCaptureViewer(ICaptureViewer *viewer) override - { - InvokeVoidFunction(&ICaptureContext::RemoveCaptureViewer, viewer); - } - virtual void AddMessages(const rdcarray &msgs) override - { - InvokeVoidFunction(&ICaptureContext::AddMessages, msgs); - } - virtual void ClearMessages() override { InvokeVoidFunction(&ICaptureContext::ClearMessages); } - virtual void SetResourceCustomName(ResourceId id, const rdcstr &name) override - { - InvokeVoidFunction(&ICaptureContext::SetResourceCustomName, id, name); - } - virtual void SetNotes(const rdcstr &key, const rdcstr &contents) override - { - InvokeVoidFunction(&ICaptureContext::SetNotes, key, contents); - } - - virtual void SetBookmark(const EventBookmark &mark) override - { - InvokeVoidFunction(&ICaptureContext::SetBookmark, mark); - } - virtual void RemoveBookmark(uint32_t EID) override - { - InvokeVoidFunction(&ICaptureContext::RemoveBookmark, EID); - } - virtual void EmbedDependentFiles() override - { - InvokeVoidFunction(&ICaptureContext::EmbedDependentFiles); - } - virtual void RemoveDependentFiles() override - { - InvokeVoidFunction(&ICaptureContext::RemoveDependentFiles); - } - virtual void DelayedCallback(uint32_t milliseconds, std::function callback) override - { - InvokeVoidFunction(&ICaptureContext::DelayedCallback, milliseconds, callback); - } - virtual IMainWindow *GetMainWindow() override - { - return InvokeRetFunction(&ICaptureContext::GetMainWindow); - } - virtual IEventBrowser *GetEventBrowser() override - { - return InvokeRetFunction(&ICaptureContext::GetEventBrowser); - } - virtual IAPIInspector *GetAPIInspector() override - { - return InvokeRetFunction(&ICaptureContext::GetAPIInspector); - } - virtual IAnnotationViewer *GetAnnotationViewer() override - { - return InvokeRetFunction(&ICaptureContext::GetAnnotationViewer); - } - virtual ITextureViewer *GetTextureViewer() override - { - return InvokeRetFunction(&ICaptureContext::GetTextureViewer); - } - virtual IBufferViewer *GetMeshPreview() override - { - return InvokeRetFunction(&ICaptureContext::GetMeshPreview); - } - virtual IPipelineStateViewer *GetPipelineViewer() override - { - return InvokeRetFunction(&ICaptureContext::GetPipelineViewer); - } - virtual ICaptureDialog *GetCaptureDialog() override - { - return InvokeRetFunction(&ICaptureContext::GetCaptureDialog); - } - virtual IDebugMessageView *GetDebugMessageView() override - { - return InvokeRetFunction(&ICaptureContext::GetDebugMessageView); - } - virtual IDiagnosticLogView *GetDiagnosticLogView() override - { - return InvokeRetFunction(&ICaptureContext::GetDiagnosticLogView); - } - virtual ICommentView *GetCommentView() override - { - return InvokeRetFunction(&ICaptureContext::GetCommentView); - } - virtual IPerformanceCounterViewer *GetPerformanceCounterViewer() override - { - return InvokeRetFunction( - &ICaptureContext::GetPerformanceCounterViewer); - } - virtual IStatisticsViewer *GetStatisticsViewer() override - { - return InvokeRetFunction(&ICaptureContext::GetStatisticsViewer); - } - virtual ITimelineBar *GetTimelineBar() override - { - return InvokeRetFunction(&ICaptureContext::GetTimelineBar); - } - virtual IPythonShell *GetPythonShell() override - { - return InvokeRetFunction(&ICaptureContext::GetPythonShell); - } - virtual IResourceInspector *GetResourceInspector() override - { - return InvokeRetFunction(&ICaptureContext::GetResourceInspector); - } - virtual bool HasEventBrowser() override - { - return InvokeRetFunction(&ICaptureContext::HasEventBrowser); - } - virtual bool HasAPIInspector() override - { - return InvokeRetFunction(&ICaptureContext::HasAPIInspector); - } - virtual bool HasAnnotationViewer() override - { - return InvokeRetFunction(&ICaptureContext::HasAnnotationViewer); - } - virtual bool HasTextureViewer() override - { - return InvokeRetFunction(&ICaptureContext::HasTextureViewer); - } - virtual bool HasPipelineViewer() override - { - return InvokeRetFunction(&ICaptureContext::HasPipelineViewer); - } - virtual bool HasMeshPreview() override - { - return InvokeRetFunction(&ICaptureContext::HasMeshPreview); - } - virtual bool HasCaptureDialog() override - { - return InvokeRetFunction(&ICaptureContext::HasCaptureDialog); - } - virtual bool HasDebugMessageView() override - { - return InvokeRetFunction(&ICaptureContext::HasDebugMessageView); - } - virtual bool HasDiagnosticLogView() override - { - return InvokeRetFunction(&ICaptureContext::HasDiagnosticLogView); - } - virtual bool HasCommentView() override - { - return InvokeRetFunction(&ICaptureContext::HasCommentView); - } - virtual bool HasPerformanceCounterViewer() override - { - return InvokeRetFunction(&ICaptureContext::HasPerformanceCounterViewer); - } - virtual bool HasStatisticsViewer() override - { - return InvokeRetFunction(&ICaptureContext::HasStatisticsViewer); - } - virtual bool HasTimelineBar() override - { - return InvokeRetFunction(&ICaptureContext::HasTimelineBar); - } - virtual bool HasPythonShell() override - { - return InvokeRetFunction(&ICaptureContext::HasPythonShell); - } - virtual bool HasResourceInspector() override - { - return InvokeRetFunction(&ICaptureContext::HasResourceInspector); - } - - virtual void ShowEventBrowser() override - { - InvokeVoidFunction(&ICaptureContext::ShowEventBrowser); - } - virtual void ShowAPIInspector() override - { - InvokeVoidFunction(&ICaptureContext::ShowAPIInspector); - } - virtual void ShowAnnotationViewer() override - { - InvokeVoidFunction(&ICaptureContext::ShowAnnotationViewer); - } - virtual void ShowTextureViewer() override - { - InvokeVoidFunction(&ICaptureContext::ShowTextureViewer); - } - virtual void ShowMeshPreview() override { InvokeVoidFunction(&ICaptureContext::ShowMeshPreview); } - virtual void ShowPipelineViewer() override - { - InvokeVoidFunction(&ICaptureContext::ShowPipelineViewer); - } - virtual void ShowCaptureDialog() override - { - InvokeVoidFunction(&ICaptureContext::ShowCaptureDialog); - } - virtual void ShowDebugMessageView() override - { - InvokeVoidFunction(&ICaptureContext::ShowDebugMessageView); - } - virtual void ShowDiagnosticLogView() override - { - InvokeVoidFunction(&ICaptureContext::ShowDiagnosticLogView); - } - virtual void ShowCommentView() override { InvokeVoidFunction(&ICaptureContext::ShowCommentView); } - virtual void ShowPerformanceCounterViewer() override - { - InvokeVoidFunction(&ICaptureContext::ShowPerformanceCounterViewer); - } - virtual void ShowStatisticsViewer() override - { - InvokeVoidFunction(&ICaptureContext::ShowStatisticsViewer); - } - virtual void ShowTimelineBar() override { InvokeVoidFunction(&ICaptureContext::ShowTimelineBar); } - virtual void ShowPythonShell() override { InvokeVoidFunction(&ICaptureContext::ShowPythonShell); } - virtual void ShowResourceInspector() override - { - InvokeVoidFunction(&ICaptureContext::ShowResourceInspector); - } - virtual IShaderViewer *EditShader(ResourceId id, ShaderStage stage, const rdcstr &entryPoint, - const rdcstrpairs &files, KnownShaderTool knownTool, - ShaderEncoding shaderEncoding, ShaderCompileFlags flags, - IShaderViewer::SaveCallback saveCallback, - IShaderViewer::RevertCallback revertCallback) override - { - return InvokeRetFunction(&ICaptureContext::EditShader, id, stage, entryPoint, - files, knownTool, shaderEncoding, flags, saveCallback, - revertCallback); - } - - virtual IShaderViewer *DebugShader(const ShaderReflection *shader, ResourceId pipeline, - ShaderDebugTrace *trace, const rdcstr &debugContext) override - { - return InvokeRetFunction(&ICaptureContext::DebugShader, shader, pipeline, - trace, debugContext); - } - - virtual IShaderViewer *ViewShader(const ShaderReflection *shader, ResourceId pipeline) override - { - return InvokeRetFunction(&ICaptureContext::ViewShader, shader, pipeline); - } - - virtual IShaderMessageViewer *ViewShaderMessages(ShaderStageMask stages) override - { - return InvokeRetFunction(&ICaptureContext::ViewShaderMessages, stages); - } - - virtual IDescriptorViewer *ViewDescriptorStore(ResourceId id) override - { - return InvokeRetFunction(&ICaptureContext::ViewDescriptorStore, id); - } - virtual IDescriptorViewer *ViewDescriptors(const rdcarray &descriptors, - const rdcarray &samplerDescriptors) override - { - return InvokeRetFunction(&ICaptureContext::ViewDescriptors, descriptors, - samplerDescriptors); - } - - virtual IBufferViewer *ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const rdcstr &format = "") override - { - return InvokeRetFunction(&ICaptureContext::ViewBuffer, byteOffset, byteSize, - id, format); - } - - virtual IBufferViewer *ViewTextureAsBuffer(ResourceId id, const Subresource &sub, - const rdcstr &format = "") override - { - return InvokeRetFunction(&ICaptureContext::ViewTextureAsBuffer, id, sub, format); - } - - virtual IBufferViewer *ViewConstantBuffer(ShaderStage stage, uint32_t slot, uint32_t idx) override - { - return InvokeRetFunction(&ICaptureContext::ViewConstantBuffer, stage, slot, idx); - } - - virtual IPixelHistoryView *ViewPixelHistory(ResourceId texID, uint32_t x, uint32_t y, - uint32_t view, const TextureDisplay &display) override - { - return InvokeRetFunction(&ICaptureContext::ViewPixelHistory, texID, x, y, - view, display); - } - - virtual QWidget *CreateBuiltinWindow(const rdcstr &objectName) override - { - return InvokeRetFunction(&ICaptureContext::CreateBuiltinWindow, objectName); - } - - virtual void BuiltinWindowClosed(QWidget *window) override - { - InvokeVoidFunction(&ICaptureContext::BuiltinWindowClosed, window); - } - - virtual void RaiseDockWindow(QWidget *dockWindow) override - { - InvokeVoidFunction(&ICaptureContext::RaiseDockWindow, dockWindow); - } - - virtual void AddDockWindow(QWidget *newWindow, DockReference ref, QWidget *refWindow, - float percentage = 0.5f) override - { - InvokeVoidFunction(&ICaptureContext::AddDockWindow, newWindow, ref, refWindow, percentage); - } -}; - void updateEditorTitle(ScintillaEdit *editor); void setEditorFilename(ScintillaEdit *editor, QString filename) @@ -1412,12 +155,16 @@ bool EditorWrapper::checkAllowClose() return true; } +// See PythonInvokers.cpp +ICaptureContext *MakeCaptureContextInvoker(PythonShell *shell, ICaptureContext &ctx); +void FreeCaptureContextInvoker(ICaptureContext *ctx); + PythonShell::PythonShell(ICaptureContext &ctx, QWidget *parent) : QFrame(parent), ui(new Ui::PythonShell), m_Ctx(ctx) { ui->setupUi(this); - m_ThreadCtx = new CaptureContextInvoker(this, m_Ctx); + m_ThreadCtx = MakeCaptureContextInvoker(this, m_Ctx); QObject::connect(ui->lineInput, &RDLineEdit::keyPress, this, &PythonShell::interactive_keypress); QObject::connect(ui->helpSearch, &RDLineEdit::keyPress, this, &PythonShell::helpSearch_keypress); @@ -1647,7 +394,7 @@ PythonShell::~PythonShell() completionContext->Finish(); interactiveContext->Finish(); - delete m_ThreadCtx; + FreeCaptureContextInvoker(m_ThreadCtx); delete ui; } @@ -3082,5 +1829,5 @@ PythonContext *PythonShell::newContext() void PythonShell::setGlobals(PythonContext *ret) { - ret->setGlobal("pyrenderdoc", (ICaptureContext *)m_ThreadCtx); + ret->setGlobal("pyrenderdoc", m_ThreadCtx); } diff --git a/qrenderdoc/Windows/PythonShell.h b/qrenderdoc/Windows/PythonShell.h index f49facfa9..80cfe97bb 100644 --- a/qrenderdoc/Windows/PythonShell.h +++ b/qrenderdoc/Windows/PythonShell.h @@ -133,7 +133,7 @@ private slots: private: Ui::PythonShell *ui; ICaptureContext &m_Ctx; - CaptureContextInvoker *m_ThreadCtx = NULL; + ICaptureContext *m_ThreadCtx = NULL; ScintillaEdit *runningScriptEditor = NULL; diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro index 5fa774ccf..87982314a 100644 --- a/qrenderdoc/qrenderdoc.pro +++ b/qrenderdoc/qrenderdoc.pro @@ -177,6 +177,7 @@ SOURCES += Code/qrenderdoc.cpp \ Code/Resources.cpp \ Code/RGPInterop.cpp \ Code/pyrenderdoc/PythonContext.cpp \ + Code/pyrenderdoc/PythonInvokers.cpp \ Code/Interface/QRDInterface.cpp \ Code/Interface/Analytics.cpp \ Code/Interface/ShaderProcessingTool.cpp \ diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj index b63aa1c79..92ea56853 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ b/qrenderdoc/qrenderdoc_local.vcxproj @@ -602,6 +602,7 @@ + diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters index 67bd04742..e77bd2d9b 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ b/qrenderdoc/qrenderdoc_local.vcxproj.filters @@ -582,6 +582,9 @@ Code\pyrenderdoc + + Code\pyrenderdoc + Generated Files