mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Backport 'tagged' render invokes from qrenderdoc
* This is a possible fix for a case where render work triggered by mouse movements (such as pixel and vertex picking) can happen faster than it executes, leading to a backlog of render commands and a noticeable lag which only gets worse the more you move the mouse until everything seems to be unresponsive or laggy (especially if you then trigger a blocking command like event change, which will block the whole UI until the queued picks happen). * Since a new pick coming in will override and make redundant the previous pick, we allow the render commands to do just that. If a new command comes in, we remove any previous commands with the same tag and put the command in the first match (this prevents a tagged invoke always being pushed to the back of the queue).
This commit is contained in:
@@ -45,12 +45,21 @@ namespace renderdocui.Code
|
||||
{
|
||||
private class InvokeHandle
|
||||
{
|
||||
public InvokeHandle(InvokeMethod m)
|
||||
public InvokeHandle(string t, InvokeMethod m)
|
||||
{
|
||||
tag = t;
|
||||
method = m;
|
||||
processed = false;
|
||||
}
|
||||
|
||||
public InvokeHandle(InvokeMethod m)
|
||||
{
|
||||
tag = "";
|
||||
method = m;
|
||||
processed = false;
|
||||
}
|
||||
|
||||
public string tag;
|
||||
public InvokeMethod method;
|
||||
public bool paintInvoke = false;
|
||||
volatile public bool processed;
|
||||
@@ -423,6 +432,55 @@ namespace renderdocui.Code
|
||||
CatchExceptions = catching;
|
||||
}
|
||||
|
||||
// this tagged version is for cases when we might send a request - e.g. to pick a vertex or pixel
|
||||
// - and want to pre-empt it with a new request before the first has returned. Either because some
|
||||
// other work is taking a while or because we're sending requests faster than they can be
|
||||
// processed.
|
||||
// the manager processes only the request on the top of the queue, so when a new tagged invoke
|
||||
// comes in, we remove any other requests in the queue before it that have the same tag
|
||||
public void BeginInvoke(string tag, InvokeMethod m)
|
||||
{
|
||||
InvokeHandle cmd = new InvokeHandle(tag, m);
|
||||
|
||||
if (tag != "")
|
||||
{
|
||||
lock (m_renderQueue)
|
||||
{
|
||||
bool added = false;
|
||||
|
||||
for (int i = 0; i < m_renderQueue.Count;)
|
||||
{
|
||||
if (m_renderQueue[i].tag == tag)
|
||||
{
|
||||
m_renderQueue[i].processed = true;
|
||||
if (!added)
|
||||
{
|
||||
m_renderQueue[i] = cmd;
|
||||
added = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_renderQueue.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!added)
|
||||
m_renderQueue.Add(cmd);
|
||||
}
|
||||
|
||||
m_WakeupEvent.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
PushInvoke(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public void BeginInvoke(InvokeMethod m)
|
||||
{
|
||||
InvokeHandle cmd = new InvokeHandle(m);
|
||||
@@ -442,7 +500,7 @@ namespace renderdocui.Code
|
||||
throw cmd.ex;
|
||||
}
|
||||
|
||||
public void InvokeForPaint(InvokeMethod m)
|
||||
public void InvokeForPaint(string tag, InvokeMethod m)
|
||||
{
|
||||
if (m_Thread == null || !Running)
|
||||
return;
|
||||
@@ -458,7 +516,7 @@ namespace renderdocui.Code
|
||||
|
||||
bool waitable = true;
|
||||
|
||||
InvokeHandle cmd = new InvokeHandle(m);
|
||||
InvokeHandle cmd = new InvokeHandle(tag, m);
|
||||
cmd.paintInvoke = true;
|
||||
|
||||
lock (m_renderQueue)
|
||||
@@ -473,7 +531,35 @@ namespace renderdocui.Code
|
||||
if (!m_renderQueue[i].paintInvoke)
|
||||
waitable = false;
|
||||
|
||||
m_renderQueue.Add(cmd);
|
||||
// remove any duplicated paints if we have a tag
|
||||
bool added = false;
|
||||
|
||||
if (tag != "")
|
||||
{
|
||||
for (int i = 0; i < m_renderQueue.Count;)
|
||||
{
|
||||
if (m_renderQueue[i].tag == tag)
|
||||
{
|
||||
m_renderQueue[i].processed = true;
|
||||
if (!added)
|
||||
{
|
||||
m_renderQueue[i] = cmd;
|
||||
added = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_renderQueue.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!added)
|
||||
m_renderQueue.Add(cmd);
|
||||
}
|
||||
|
||||
m_WakeupEvent.Set();
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace renderdocui.Controls
|
||||
}
|
||||
|
||||
if (m_Output != null)
|
||||
m_Core.Renderer.InvokeForPaint((ReplayRenderer r) => { m_Output.Display(); });
|
||||
m_Core.Renderer.InvokeForPaint("thumbpaint", (ReplayRenderer r) => { m_Output.Display(); });
|
||||
}
|
||||
|
||||
public void SetSize(Size s)
|
||||
|
||||
@@ -2391,7 +2391,7 @@ namespace renderdocui.Windows
|
||||
if (!m_Core.LogLoaded)
|
||||
return;
|
||||
|
||||
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
|
||||
m_Core.Renderer.BeginInvoke("PickVertex", (ReplayRenderer r) =>
|
||||
{
|
||||
UInt32 instanceSelected = 0;
|
||||
UInt32 vertSelected = m_Output.PickVertex(m_Core.CurEvent, (UInt32)p.X, (UInt32)p.Y, out instanceSelected);
|
||||
@@ -2598,7 +2598,7 @@ namespace renderdocui.Windows
|
||||
return;
|
||||
}
|
||||
|
||||
m_Core.Renderer.InvokeForPaint((ReplayRenderer r) => { RT_UpdateRenderOutput(r); if (m_Output != null) m_Output.Display(); });
|
||||
m_Core.Renderer.InvokeForPaint("bufferpaint", (ReplayRenderer r) => { RT_UpdateRenderOutput(r); if (m_Output != null) m_Output.Display(); });
|
||||
}
|
||||
|
||||
private void BufferViewer_Load(object sender, EventArgs e)
|
||||
|
||||
@@ -2452,7 +2452,7 @@ namespace renderdocui.Windows
|
||||
return;
|
||||
}
|
||||
|
||||
m_Core.Renderer.InvokeForPaint((ReplayRenderer r) => { if (m_Output != null) m_Output.Display(); });
|
||||
m_Core.Renderer.InvokeForPaint("contextpaint", (ReplayRenderer r) => { if (m_Output != null) m_Output.Display(); });
|
||||
}
|
||||
|
||||
private void render_Paint(object sender, PaintEventArgs e)
|
||||
@@ -2470,7 +2470,7 @@ namespace renderdocui.Windows
|
||||
foreach (var prev in roPanel.Thumbnails)
|
||||
if (prev.Unbound) prev.Clear();
|
||||
|
||||
m_Core.Renderer.InvokeForPaint((ReplayRenderer r) => { if (m_Output != null) m_Output.Display(); });
|
||||
m_Core.Renderer.InvokeForPaint("texpaint", (ReplayRenderer r) => { if (m_Output != null) m_Output.Display(); });
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -2910,7 +2910,7 @@ namespace renderdocui.Windows
|
||||
m_PickedPoint.X = Helpers.Clamp(m_PickedPoint.X, 0, (int)tex.width - 1);
|
||||
m_PickedPoint.Y = Helpers.Clamp(m_PickedPoint.Y, 0, (int)tex.height - 1);
|
||||
|
||||
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
|
||||
m_Core.Renderer.BeginInvoke("PickPixelClick", (ReplayRenderer r) =>
|
||||
{
|
||||
if (m_Output != null)
|
||||
RT_PickPixelsAndUpdate(m_PickedPoint.X, m_PickedPoint.Y, true);
|
||||
@@ -2926,7 +2926,7 @@ namespace renderdocui.Windows
|
||||
|
||||
if (tex != null)
|
||||
{
|
||||
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
|
||||
m_Core.Renderer.BeginInvoke("PickPixelHover", (ReplayRenderer r) =>
|
||||
{
|
||||
if (m_Output != null)
|
||||
{
|
||||
@@ -3289,7 +3289,7 @@ namespace renderdocui.Windows
|
||||
|
||||
rangePaintThread = Helpers.NewThread(new ThreadStart(() =>
|
||||
{
|
||||
m_Core.Renderer.InvokeForPaint((ReplayRenderer r) => { RT_UpdateAndDisplay(r); if (m_Output != null) m_Output.Display(); });
|
||||
m_Core.Renderer.InvokeForPaint("", (ReplayRenderer r) => { RT_UpdateAndDisplay(r); if (m_Output != null) m_Output.Display(); });
|
||||
Thread.Sleep(8);
|
||||
}));
|
||||
rangePaintThread.Start();
|
||||
|
||||
Reference in New Issue
Block a user