mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-12 21:10:42 +00:00
Add skeleton (untested) of RenderManager handling its own thread
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
#ifndef CORE_H
|
||||
#define CORE_H
|
||||
|
||||
#include "RenderManager.h"
|
||||
|
||||
class Core
|
||||
{
|
||||
public:
|
||||
Core();
|
||||
~Core();
|
||||
|
||||
const RenderManager *Renderer() { return &m_Renderer; }
|
||||
|
||||
private:
|
||||
RenderManager m_Renderer;
|
||||
};
|
||||
|
||||
#endif // CORE_H
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
#include "RenderManager.h"
|
||||
|
||||
#include <QMutexLocker>
|
||||
|
||||
RenderManager::RenderManager()
|
||||
{
|
||||
m_Running = false;
|
||||
}
|
||||
|
||||
RenderManager::~RenderManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RenderManager::Init(int proxyRenderer, QString replayHost, QString logfile, float *progress)
|
||||
{
|
||||
if(m_Running)
|
||||
return;
|
||||
|
||||
m_ProxyRenderer = proxyRenderer;
|
||||
m_ReplayHost = replayHost;
|
||||
m_Logfile = logfile;
|
||||
m_Progress = progress;
|
||||
|
||||
*progress = 0.0f;
|
||||
|
||||
start(HighestPriority);
|
||||
|
||||
while (!isRunning()) {}
|
||||
}
|
||||
|
||||
void RenderManager::AsyncInvoke(RenderManager::InvokeMethod m)
|
||||
{
|
||||
InvokeHandle *cmd = new InvokeHandle(m);
|
||||
cmd->selfdelete = true;
|
||||
|
||||
PushInvoke(cmd);
|
||||
}
|
||||
|
||||
void RenderManager::BlockInvoke(RenderManager::InvokeMethod m)
|
||||
{
|
||||
InvokeHandle *cmd = new InvokeHandle(m);
|
||||
|
||||
PushInvoke(cmd);
|
||||
|
||||
while(!cmd->processed) {}
|
||||
}
|
||||
|
||||
void RenderManager::CloseThread()
|
||||
{
|
||||
m_Running = false;
|
||||
|
||||
m_RenderCondition.wakeAll();
|
||||
|
||||
// wait for the thread to close and clean up
|
||||
while(isRunning()) {}
|
||||
}
|
||||
|
||||
void RenderManager::PushInvoke(RenderManager::InvokeHandle *cmd)
|
||||
{
|
||||
if(!isRunning() || !m_Running)
|
||||
{
|
||||
cmd->processed = true;
|
||||
if(cmd->selfdelete) delete cmd;
|
||||
return;
|
||||
}
|
||||
|
||||
m_RenderLock.lock();
|
||||
m_RenderQueue.push_back(cmd);
|
||||
m_RenderLock.unlock();
|
||||
|
||||
m_RenderCondition.wakeAll();
|
||||
}
|
||||
|
||||
void RenderManager::run()
|
||||
{
|
||||
IReplayRenderer *renderer = NULL;
|
||||
IRemoteRenderer *remote = NULL;
|
||||
|
||||
if (m_ProxyRenderer < 0)
|
||||
{
|
||||
m_CreateStatus = RENDERDOC_CreateReplayRenderer(m_Logfile.toUtf8(), m_Progress, &renderer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CreateStatus = RENDERDOC_CreateRemoteReplayConnection(m_ReplayHost.toUtf8(), &remote);
|
||||
|
||||
if(remote == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_CreateStatus = remote->CreateProxyRenderer(m_ProxyRenderer, m_Logfile.toUtf8(), m_Progress, &renderer);
|
||||
|
||||
if(renderer == NULL)
|
||||
{
|
||||
remote->Shutdown();
|
||||
remote = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(renderer == NULL)
|
||||
return;
|
||||
|
||||
RENDERDOC_LogText(QString("QRenderDoc - renderer created for %1").arg(m_Logfile).toUtf8());
|
||||
|
||||
m_Running = true;
|
||||
|
||||
// main render command loop
|
||||
while(m_Running)
|
||||
{
|
||||
QQueue<InvokeHandle *> queue;
|
||||
|
||||
// wait for the condition to be woken, grab current queue,
|
||||
// unlock again.
|
||||
{
|
||||
m_RenderLock.lock();
|
||||
m_RenderCondition.wait(&m_RenderLock);
|
||||
m_RenderQueue.swap(queue);
|
||||
m_RenderLock.unlock();
|
||||
}
|
||||
|
||||
// process all the commands
|
||||
for(InvokeHandle *cmd : queue)
|
||||
{
|
||||
if(cmd == NULL) continue;
|
||||
|
||||
if(cmd->method != NULL)
|
||||
cmd->method(renderer);
|
||||
|
||||
cmd->processed = true;
|
||||
|
||||
// if it's a throwaway command, delete it
|
||||
if(cmd->selfdelete)
|
||||
delete cmd;
|
||||
}
|
||||
}
|
||||
|
||||
// clean up anything left in the queue
|
||||
{
|
||||
QQueue<InvokeHandle *> queue;
|
||||
|
||||
m_RenderLock.lock();
|
||||
m_RenderQueue.swap(queue);
|
||||
m_RenderLock.unlock();
|
||||
|
||||
for(InvokeHandle *cmd : queue)
|
||||
{
|
||||
if(cmd == NULL) continue;
|
||||
|
||||
cmd->processed = true;
|
||||
|
||||
if(cmd->selfdelete)
|
||||
delete cmd;
|
||||
}
|
||||
}
|
||||
|
||||
// close the core renderer
|
||||
renderer->Shutdown();
|
||||
if(remote) remote->Shutdown();
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef RENDERMANAGER_H
|
||||
#define RENDERMANAGER_H
|
||||
|
||||
#include "renderdoc_replay.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QQueue>
|
||||
#include <QWaitCondition>
|
||||
|
||||
struct IReplayRenderer;
|
||||
|
||||
class RenderManager : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
void run();
|
||||
|
||||
public:
|
||||
typedef void (*InvokeMethod)(IReplayRenderer *r);
|
||||
|
||||
RenderManager();
|
||||
~RenderManager();
|
||||
|
||||
void Init(int proxyRenderer, QString replayHost, QString logfile, float *progress);
|
||||
|
||||
bool IsRunning() { return isRunning() && m_Running; }
|
||||
ReplayCreateStatus GetCreateStatus() { return m_CreateStatus; }
|
||||
|
||||
void AsyncInvoke(InvokeMethod m);
|
||||
void BlockInvoke(InvokeMethod m);
|
||||
|
||||
void CloseThread();
|
||||
private:
|
||||
|
||||
struct InvokeHandle
|
||||
{
|
||||
InvokeHandle(InvokeMethod m)
|
||||
{
|
||||
method = m;
|
||||
processed = false;
|
||||
selfdelete = true;
|
||||
}
|
||||
|
||||
InvokeMethod method;
|
||||
bool processed;
|
||||
bool selfdelete;
|
||||
};
|
||||
|
||||
QMutex m_RenderLock;
|
||||
QQueue<InvokeHandle *> m_RenderQueue;
|
||||
QWaitCondition m_RenderCondition;
|
||||
|
||||
void PushInvoke(InvokeHandle *cmd);
|
||||
|
||||
int m_ProxyRenderer;
|
||||
QString m_ReplayHost;
|
||||
QString m_Logfile;
|
||||
float *m_Progress;
|
||||
|
||||
volatile bool m_Running;
|
||||
ReplayCreateStatus m_CreateStatus;
|
||||
};
|
||||
|
||||
#endif // RENDERMANAGER_H
|
||||
@@ -59,7 +59,8 @@ SOURCES += Code/main.cpp \
|
||||
Widgets/CustomPaintWidget.cpp \
|
||||
3rdparty/toolwindowmanager/ToolWindowManager.cpp \
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerArea.cpp \
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerWrapper.cpp
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerWrapper.cpp \
|
||||
Code/RenderManager.cpp
|
||||
|
||||
HEADERS += Windows/MainWindow.h \
|
||||
Windows/EventBrowser.h \
|
||||
@@ -68,7 +69,8 @@ HEADERS += Windows/MainWindow.h \
|
||||
3rdparty/toolwindowmanager/ToolWindowManager.h \
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerArea.h \
|
||||
3rdparty/toolwindowmanager/ToolWindowManagerWrapper.h \
|
||||
Code/Core.h
|
||||
Code/Core.h \
|
||||
Code/RenderManager.h
|
||||
|
||||
FORMS += Windows/MainWindow.ui \
|
||||
Windows/EventBrowser.ui \
|
||||
|
||||
Reference in New Issue
Block a user