From 5406227152c22b46f49a74669f700852f929ea17 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 31 Aug 2018 20:32:56 +0100 Subject: [PATCH] Call CreateWindowingData on the main UI thread * This allows mac to patch-up the widget to be renderable, and has to happen on the UI thread. --- qrenderdoc/Code/CaptureContext.cpp | 20 ++++++++++-------- qrenderdoc/Code/CaptureContext.h | 2 +- qrenderdoc/Code/Interface/QRDInterface.h | 7 +++++-- qrenderdoc/Windows/BufferViewer.cpp | 6 +++--- qrenderdoc/Windows/MainWindow.cpp | 4 ++-- qrenderdoc/Windows/PythonShell.cpp | 8 ++++---- qrenderdoc/Windows/TextureViewer.cpp | 26 ++++++++++++------------ 7 files changed, 39 insertions(+), 34 deletions(-) diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index 196c02af5..be7c9ce58 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -1197,23 +1197,25 @@ int CaptureContext::ResourceNameCacheID() return m_CustomNameCachedID; } -WindowingData CaptureContext::CreateWindowingData(uintptr_t widget) +#if defined(RENDERDOC_PLATFORM_APPLE) +extern "C" void makeNSViewMetalCompatible(void *handle); +#endif + +WindowingData CaptureContext::CreateWindowingData(QWidget *window) { + if(!GUIInvoke::onUIThread()) + qCritical() << "CreateWindowingData called on non-UI thread"; + #if defined(WIN32) - return CreateWin32WindowingData((HWND)widget); + return CreateWin32WindowingData((HWND)window->winId()); #elif defined(RENDERDOC_PLATFORM_LINUX) if(m_CurWinSystem == WindowingSystem::XCB) - return CreateXCBWindowingData(m_XCBConnection, (xcb_window_t)widget); + return CreateXCBWindowingData(m_XCBConnection, (xcb_window_t)window->winId()); else - return CreateXlibWindowingData(m_X11Display, (Drawable)widget); - -#elif defined(RENDERDOC_PLATFORM_APPLE) - - WindowingData ret = {WindowingSystem::Unknown}; - return ret; + return CreateXlibWindowingData(m_X11Display, (Drawable)window->winId()); #else diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index bde4cad5e..6b94f7a5d 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -137,7 +137,7 @@ public: } const SDFile &GetStructuredFile() override { return *m_StructuredFile; } WindowingSystem CurWindowingSystem() override { return m_CurWinSystem; } - WindowingData CreateWindowingData(uintptr_t winId) override; + WindowingData CreateWindowingData(QWidget *window) override; const rdcarray &DebugMessages() override { return m_DebugMessages; } int UnreadMessageCount() override { return m_UnreadMessageCount; } diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index aa10f970e..fbd18bcd9 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -1419,11 +1419,14 @@ called. DOCUMENT(R"(Create an opaque pointer suitable for passing to :meth:`~renderdoc.ReplayController.CreateOutput` or other functions that expect windowing data. -:param int winId: The window ID as returned from ``QWidget.winId()``. +.. note:: + This function must be called on the main UI thread. + +:param QWidget window: The window to create windowing data for. :return: The windowing data. :rtype: ~renderdoc.WindowingData )"); - virtual WindowingData CreateWindowingData(uintptr_t winId) = 0; + virtual WindowingData CreateWindowingData(QWidget *window) = 0; DOCUMENT(R"(Retrieve the current list of debug messages. This includes messages from the capture as well as messages generated during replay and analysis. diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index d7c3b6728..41cb69217 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -1373,10 +1373,10 @@ void BufferViewer::OnCaptureLoaded() if(!m_MeshView) return; - WId renderID = ui->render->winId(); + WindowingData winData = m_Ctx.CreateWindowingData(ui->render); - m_Ctx.Replay().BlockInvoke([renderID, this](IReplayController *r) { - m_Output = r->CreateOutput(m_Ctx.CreateWindowingData(renderID), ReplayOutputType::Mesh); + m_Ctx.Replay().BlockInvoke([winData, this](IReplayController *r) { + m_Output = r->CreateOutput(winData, ReplayOutputType::Mesh); ui->render->setOutput(m_Output); diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 7b96fb99f..6569f2bef 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -2327,7 +2327,7 @@ void MainWindow::on_action_Start_Replay_Loop_triggered() .arg(tr("nothing"))); } - WindowingData winData = m_Ctx.CreateWindowingData(popup.winId()); + WindowingData winData = m_Ctx.CreateWindowingData(&popup); m_Ctx.Replay().AsyncInvoke([winData, id](IReplayController *r) { r->ReplayLoop(winData, id); }); @@ -2386,7 +2386,7 @@ void MainWindow::on_action_Create_RGP_Profile_triggered() popup.resize(128, 16); popup.setWindowTitle(tr("Making RGP Profile from %1").arg(m_Ctx.GetCaptureFilename())); - WindowingData winData = m_Ctx.CreateWindowingData(popup.winId()); + WindowingData winData = m_Ctx.CreateWindowingData(&popup); rdcstr path; diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp index 685ae6d63..806f73c81 100644 --- a/qrenderdoc/Windows/PythonShell.cpp +++ b/qrenderdoc/Windows/PythonShell.cpp @@ -111,10 +111,6 @@ struct CaptureContextInvoker : ICaptureContext virtual IRGPInterop *GetRGPInterop() override { return m_Ctx.GetRGPInterop(); } virtual const SDFile &GetStructuredFile() override { return m_Ctx.GetStructuredFile(); } virtual WindowingSystem CurWindowingSystem() override { return m_Ctx.CurWindowingSystem(); } - virtual WindowingData CreateWindowingData(uintptr_t winId) override - { - return m_Ctx.CreateWindowingData(winId); - } virtual const rdcarray &DebugMessages() override { return m_Ctx.DebugMessages(); } virtual int UnreadMessageCount() override { return m_Ctx.UnreadMessageCount(); } virtual void MarkMessagesRead() override { return m_Ctx.MarkMessagesRead(); } @@ -168,6 +164,10 @@ struct CaptureContextInvoker : ICaptureContext return (m_Ctx.*ptr)(params...); } + virtual WindowingData CreateWindowingData(QWidget *window) override + { + return InvokeRetFunction(&ICaptureContext::CreateWindowingData, window); + } virtual void LoadCapture(const rdcstr &capture, const rdcstr &origFilename, bool temporary, bool local) override { diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index 1972156e9..5be88a06c 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -1965,18 +1965,18 @@ void TextureViewer::InitResourcePreview(ResourcePreview *prev, ResourceId id, Co prev->setResourceName(fullname); - WId handle = prev->thumbWinId(); + WindowingData winData = m_Ctx.CreateWindowingData(prev); if(m_Ctx.GetTexture(id)) { - m_Ctx.Replay().AsyncInvoke([this, handle, id, typeHint](IReplayController *) { - m_Output->AddThumbnail(m_Ctx.CreateWindowingData(handle), id, typeHint); + m_Ctx.Replay().AsyncInvoke([this, winData, id, typeHint](IReplayController *) { + m_Output->AddThumbnail(winData, id, typeHint); }); } else { - m_Ctx.Replay().AsyncInvoke([this, handle](IReplayController *) { - m_Output->AddThumbnail(m_Ctx.CreateWindowingData(handle), ResourceId(), CompType::Typeless); + m_Ctx.Replay().AsyncInvoke([this, winData](IReplayController *) { + m_Output->AddThumbnail(winData, ResourceId(), CompType::Typeless); }); } @@ -1991,9 +1991,9 @@ void TextureViewer::InitResourcePreview(ResourcePreview *prev, ResourceId id, Co prev->setActive(true); prev->setSelected(true); - WId handle = prev->thumbWinId(); - m_Ctx.Replay().AsyncInvoke([this, handle](IReplayController *) { - m_Output->AddThumbnail(m_Ctx.CreateWindowingData(handle), ResourceId(), CompType::Typeless); + WindowingData winData = m_Ctx.CreateWindowingData(prev); + m_Ctx.Replay().AsyncInvoke([this, winData](IReplayController *) { + m_Output->AddThumbnail(winData, ResourceId(), CompType::Typeless); }); } else @@ -2504,8 +2504,8 @@ void TextureViewer::OnCaptureLoaded() { Reset(); - WId renderID = ui->render->winId(); - WId contextID = ui->pixelContext->winId(); + WindowingData renderData = m_Ctx.CreateWindowingData(ui->render); + WindowingData contextData = m_Ctx.CreateWindowingData(ui->pixelContext); ui->saveTex->setEnabled(true); ui->locationGoto->setEnabled(true); @@ -2541,10 +2541,10 @@ void TextureViewer::OnCaptureLoaded() backCol.isValid() ? FloatVector(backCol.redF(), backCol.greenF(), backCol.blueF(), 1.0f) : FloatVector(); - m_Ctx.Replay().BlockInvoke([renderID, contextID, this](IReplayController *r) { - m_Output = r->CreateOutput(m_Ctx.CreateWindowingData(renderID), ReplayOutputType::Texture); + m_Ctx.Replay().BlockInvoke([renderData, contextData, this](IReplayController *r) { + m_Output = r->CreateOutput(renderData, ReplayOutputType::Texture); - m_Output->SetPixelContext(m_Ctx.CreateWindowingData(contextID)); + m_Output->SetPixelContext(contextData); ui->render->setOutput(m_Output); ui->pixelContext->setOutput(m_Output);