Close some minor UX holes when live-connected but without replay context

* If there's no replay context we can still use the live connection to
  copy and delete captures remotely. Try to use that whenever possible
  and warn the user when it's not possible (i.e if the program has been
  closed and there's no replay context, we have no way to access the
  files anymore).
* If the user tries to open a remote log without a replay context,
  prompt them either to swithc to a replay context on that host or to
  save the log locally.
This commit is contained in:
baldurk
2016-08-30 11:55:36 +02:00
parent 279aa72064
commit a35c88e577
4 changed files with 143 additions and 7 deletions
+3
View File
@@ -435,6 +435,7 @@ struct ITargetControl
virtual void TriggerCapture(uint32_t numFrames) = 0;
virtual void QueueCapture(uint32_t frameNumber) = 0;
virtual void CopyCapture(uint32_t remoteID, const char *localpath) = 0;
virtual void DeleteCapture(uint32_t remoteID) = 0;
virtual void ReceiveMessage(TargetControlMessage *msg) = 0;
};
@@ -467,6 +468,8 @@ extern "C" RENDERDOC_API void RENDERDOC_CC TargetControl_QueueCapture(TargetCont
extern "C" RENDERDOC_API void RENDERDOC_CC TargetControl_CopyCapture(TargetControl *control,
uint32_t remoteID,
const char *localpath);
extern "C" RENDERDOC_API void RENDERDOC_CC TargetControl_DeleteCapture(TargetControl *control,
uint32_t remoteID);
extern "C" RENDERDOC_API void RENDERDOC_CC TargetControl_ReceiveMessage(TargetControl *control,
TargetControlMessage *msg);
+28
View File
@@ -39,6 +39,7 @@ enum PacketType
ePacket_RegisterAPI,
ePacket_TriggerCapture,
ePacket_CopyCapture,
ePacket_DeleteCapture,
ePacket_QueueCapture,
ePacket_NewChild,
};
@@ -177,6 +178,14 @@ void RenderDoc::TargetControlClientThread(void *s)
RenderDoc::Inst().QueueCapture(frameNum);
}
else if(type == ePacket_DeleteCapture)
{
uint32_t id = 0;
recvser->Serialise("", id);
// this means it will be deleted on shutdown
RenderDoc::Inst().MarkCaptureRetrieved(id);
}
else if(type == ePacket_CopyCapture)
{
caps = RenderDoc::Inst().GetCaptures();
@@ -465,6 +474,19 @@ public:
m_CaptureCopies[remoteID] = localpath;
}
void DeleteCapture(uint32_t remoteID)
{
Serialiser ser("", Serialiser::WRITING, false);
ser.Serialise("", remoteID);
if(!SendPacket(m_Socket, ePacket_DeleteCapture, ser))
{
SAFE_DELETE(m_Socket);
return;
}
}
void ReceiveMessage(TargetControlMessage *msg)
{
if(m_Socket == NULL)
@@ -664,6 +686,12 @@ extern "C" RENDERDOC_API void RENDERDOC_CC TargetControl_CopyCapture(TargetContr
control->CopyCapture(remoteID, localpath);
}
extern "C" RENDERDOC_API void RENDERDOC_CC TargetControl_DeleteCapture(TargetControl *control,
uint32_t remoteID)
{
control->DeleteCapture(remoteID);
}
extern "C" RENDERDOC_API void RENDERDOC_CC TargetControl_ReceiveMessage(TargetControl *control,
TargetControlMessage *msg)
{
+7
View File
@@ -1135,6 +1135,8 @@ namespace renderdoc
private static extern void TargetControl_QueueCapture(IntPtr real, UInt32 frameNumber);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern void TargetControl_CopyCapture(IntPtr real, UInt32 remoteID, IntPtr localpath);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern void TargetControl_DeleteCapture(IntPtr real, UInt32 remoteID);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern void TargetControl_ReceiveMessage(IntPtr real, IntPtr outmsg);
@@ -1213,6 +1215,11 @@ namespace renderdoc
CustomMarshal.Free(localpath_mem);
}
public void DeleteCapture(UInt32 id)
{
TargetControl_DeleteCapture(m_Real, id);
}
public void ReceiveMessage()
{
if (m_Real != IntPtr.Zero)
+105 -7
View File
@@ -60,6 +60,10 @@ namespace renderdocui.Windows
bool m_Disconnect = false;
TargetControl m_Connection = null;
uint m_CopyLogID = uint.MaxValue;
string m_CopyLogLocalPath = "";
List<uint> m_DeleteLogs = new List<uint>();
bool m_IgnoreThreadClosed = false;
string m_Host;
@@ -197,6 +201,23 @@ namespace renderdocui.Windows
m_CaptureFrameNum = 0;
}
if (m_CopyLogLocalPath != "")
{
m_Connection.CopyCapture(m_CopyLogID, m_CopyLogLocalPath);
m_CopyLogLocalPath = "";
m_CopyLogID = uint.MaxValue;
}
List<uint> dels = new List<uint>();
lock (m_DeleteLogs)
{
dels.AddRange(m_DeleteLogs);
m_DeleteLogs.Clear();
}
foreach(var del in dels)
m_Connection.DeleteCapture(del);
if (m_Disconnect)
{
m_Connection.Shutdown();
@@ -236,6 +257,13 @@ namespace renderdocui.Windows
{
uint capID = m_Connection.CaptureFile.ID;
string path = m_Connection.CaptureFile.path;
this.BeginInvoke((MethodInvoker)delegate
{
CaptureCopied(capID, path);
});
m_Connection.CaptureCopied = false;
}
if (m_Connection.ChildAdded)
@@ -363,8 +391,22 @@ namespace renderdocui.Windows
private void OpenCapture(CaptureLog log)
{
m_Main.LoadLogfile(log.path, !log.saved, log.local);
log.opened = true;
if (!log.local &&
(m_Core.Renderer.Remote == null ||
m_Core.Renderer.Remote.Hostname != m_Host ||
!m_Core.Renderer.Remote.Connected)
)
{
MessageBox.Show(
String.Format("This capture is on remote host {0} and there is no active replay context on that host.\n" +
"You can either save the log locally, or switch to a replay context on {0}.\n\n", m_Host),
"No active replay context", MessageBoxButtons.OK);
return;
}
m_Main.LoadLogfile(log.path, !log.saved, log.local);
}
private bool SaveCapture(CaptureLog log)
@@ -381,8 +423,25 @@ namespace renderdocui.Windows
{
File.Copy(log.path, path, true);
}
else if (m_Connection.Connected)
{
// if we have a current live connection, prefer using it
m_CopyLogLocalPath = path;
m_CopyLogID = log.remoteID;
}
else
{
if (m_Core.Renderer.Remote == null ||
m_Core.Renderer.Remote.Hostname != m_Host ||
!m_Core.Renderer.Remote.Connected)
{
MessageBox.Show(
String.Format("This capture is on remote host {0} and there is no active replay context on that host.\n" +
"Without an active replay context the capture cannot be saved, try switching to a replay context on {0}.\n\n", m_Host),
"No active replay context", MessageBoxButtons.OK);
return false;
}
m_Core.Renderer.CopyCaptureFromRemote(log.path, path, this);
m_Core.Renderer.DeleteCapture(log.path, false);
}
@@ -435,15 +494,15 @@ namespace renderdocui.Windows
}
// we either have to save or delete the log. Make sure that if it's remote that we are able
// to by having an active replay context on that host.
if (suppressRemoteWarning == false &&
// to by having an active connection or replay context on that host.
if (suppressRemoteWarning == false && !m_Connection.Connected &&
(m_Core.Renderer.Remote == null ||
m_Core.Renderer.Remote.Hostname != m_Host ||
!m_Core.Renderer.Remote.Connected)
)
{
DialogResult res2 = MessageBox.Show(
String.Format("This connection is to a remote host {0} and there is no active replay context on that host.\n", m_Host) +
String.Format("This capture is on remote host {0} and there is no active replay context on that host.\n", m_Host) +
"Without an active replay context the capture cannot be " + (res == DialogResult.Yes ? "saved.\n\n" : "deleted.\n\n") +
"Would you like to continue and discard this capture and any others, to be left in the temporary folder on the remote machine?",
"No active replay context", MessageBoxButtons.YesNoCancel);
@@ -492,7 +551,18 @@ namespace renderdocui.Windows
}
else
{
m_Core.Renderer.DeleteCapture(log.path, log.local);
// if connected, prefer using the live connection
if (m_Connection.Connected && !log.local)
{
lock (m_DeleteLogs)
{
m_DeleteLogs.Add(log.remoteID);
}
}
else
{
m_Core.Renderer.DeleteCapture(log.path, log.local);
}
}
}
catch (System.Exception)
@@ -512,6 +582,7 @@ namespace renderdocui.Windows
return;
}
CleanItems();
KillThread();
}
@@ -532,8 +603,8 @@ namespace renderdocui.Windows
captures.LargeImageList.Images.Clear();
thumbs.Dispose();
KillThread();
CleanItems();
KillThread();
}
private bool CheckAllowDelete()
@@ -577,7 +648,18 @@ namespace renderdocui.Windows
try
{
m_Core.Renderer.DeleteCapture(log.path, log.local);
// if connected, prefer using the live connection
if (m_Connection.Connected && !log.local)
{
lock (m_DeleteLogs)
{
m_DeleteLogs.Add(log.remoteID);
}
}
else
{
m_Core.Renderer.DeleteCapture(log.path, log.local);
}
}
catch (System.Exception)
{
@@ -650,6 +732,22 @@ namespace renderdocui.Windows
}
}
private void CaptureCopied(uint ID, string localPath)
{
foreach (ListViewItem item in captures.Items)
{
var log = item.Tag as CaptureLog;
if (log != null && log.remoteID == ID)
{
log.local = true;
log.path = localPath;
item.SubItems[0].Text = log.exe;
item.SubItems[0].Font = new Font(item.SubItems[0].Font, FontStyle.Regular);
}
}
}
private void CaptureAdded(uint ID, string executable, string api, byte[] thumbnail, DateTime timestamp, string path, bool local)
{
if (thumbnail == null || thumbnail.Length == 0)