Partially implemented support for capturing & opening logs in a context

This commit is contained in:
baldurk
2016-08-03 19:20:12 +02:00
parent 14c17cf5a5
commit 84baa6d752
9 changed files with 181 additions and 131 deletions
+2 -1
View File
@@ -211,7 +211,8 @@ struct TargetControlMessage
uint32_t ID;
uint64_t timestamp;
rdctype::array<byte> thumbnail;
rdctype::str localpath;
rdctype::str path;
bool32 local;
} NewCapture;
struct RegisterAPIData
+4 -6
View File
@@ -532,9 +532,9 @@ public:
SAFE_DELETE(ser);
msg->NewCapture.localpath = m_CaptureCopies[msg->NewCapture.ID];
msg->NewCapture.path = m_CaptureCopies[msg->NewCapture.ID];
if(!RecvChunkedFile(m_Socket, ePacket_CopyCapture, msg->NewCapture.localpath.elems, ser, NULL))
if(!RecvChunkedFile(m_Socket, ePacket_CopyCapture, msg->NewCapture.path.elems, ser, NULL))
{
SAFE_DELETE(ser);
SAFE_DELETE(m_Socket);
@@ -571,10 +571,8 @@ public:
string path;
ser->Serialise("", path);
msg->NewCapture.localpath = path;
if(!m_Local)
msg->NewCapture.localpath = "";
msg->NewCapture.path = path;
msg->NewCapture.local = m_Local;
uint32_t thumblen = 0;
ser->Serialise("", thumblen);
+11 -8
View File
@@ -451,7 +451,7 @@ namespace renderdocui.Code
}
}
public void LoadLogfile(string logFile, bool temporary)
public void LoadLogfile(string logFile, bool temporary, bool local)
{
m_LogFile = logFile;
@@ -503,7 +503,7 @@ namespace renderdocui.Code
thread.Start();
// this function call will block until the log is either loaded, or there's some failure
m_Renderer.Init(logFile);
m_Renderer.OpenCapture(logFile);
// if the renderer isn't running, we hit a failure case so display an error message
if (!m_Renderer.Running)
@@ -598,12 +598,15 @@ namespace renderdocui.Code
m_LogLoaded = true;
progressThread = false;
m_LogWatcher = new FileSystemWatcher(Path.GetDirectoryName(m_LogFile), Path.GetFileName(m_LogFile));
m_LogWatcher.EnableRaisingEvents = true;
m_LogWatcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite;
m_LogWatcher.Created += new FileSystemEventHandler(OnLogfileChanged);
m_LogWatcher.Changed += new FileSystemEventHandler(OnLogfileChanged);
m_LogWatcher.SynchronizingObject = m_MainWindow; // callbacks on UI thread please
if (local)
{
m_LogWatcher = new FileSystemWatcher(Path.GetDirectoryName(m_LogFile), Path.GetFileName(m_LogFile));
m_LogWatcher.EnableRaisingEvents = true;
m_LogWatcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite;
m_LogWatcher.Created += new FileSystemEventHandler(OnLogfileChanged);
m_LogWatcher.Changed += new FileSystemEventHandler(OnLogfileChanged);
m_LogWatcher.SynchronizingObject = m_MainWindow; // callbacks on UI thread please
}
List<ILogViewerForm> logviewers = new List<ILogViewerForm>();
logviewers.AddRange(m_LogViewers);
+15
View File
@@ -117,6 +117,21 @@ namespace renderdocui.Code
return (float)(0.2126 * Math.Pow(c.R * 255.0, 2.2) + 0.7152 * Math.Pow(c.G * 255.0, 2.2) + 0.0722 * Math.Pow(c.B * 255.0, 2.2));
}
public static int CharCount(string s, char c)
{
int ret = 0;
int offs = s.IndexOf(c);
while (offs >= 0)
{
ret++;
offs = s.IndexOf(c, offs + 1);
}
return ret;
}
public static string SafeGetFileName(string filename)
{
try
+42 -1
View File
@@ -77,7 +77,7 @@ namespace renderdocui.Code
m_renderQueue = new List<InvokeHandle>();
}
public void Init(string logfile)
public void OpenCapture(string logfile)
{
if(Running)
return;
@@ -95,6 +95,47 @@ namespace renderdocui.Code
while (m_Thread.IsAlive && !Running) ;
}
public UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, string logfile, CaptureOptions opts)
{
if (m_Remote == null)
{
return StaticExports.ExecuteAndInject(app, workingDir, cmdLine, logfile, opts);
}
else
{
return m_Remote.ExecuteAndInject(app, workingDir, cmdLine, opts);
}
}
public bool IsRemoteConnected
{
get
{
return m_Remote != null;
}
}
public void DeleteCapture(string logfile, bool local)
{
if (Running)
{
BeginInvoke((ReplayRenderer r) => { DeleteCapture(logfile, local); });
return;
}
if (local)
{
System.IO.File.Delete(logfile);
}
else
{
// this will be cleaned up automatically when the remote connection
// is closed.
if (m_Remote != null)
m_Remote.TakeOwnershipCapture(logfile);
}
}
public bool Running
{
get { return m_Running; }
+3 -2
View File
@@ -42,7 +42,8 @@ namespace renderdoc
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public byte[] thumbnail;
[CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)]
public string localpath;
public string path;
public bool local;
};
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
public NewCaptureData NewCapture;
@@ -1119,7 +1120,7 @@ namespace renderdoc
else if (msg.Type == TargetControlMessageType.CaptureCopied)
{
CaptureFile.ID = msg.NewCapture.ID;
CaptureFile.localpath = msg.NewCapture.localpath;
CaptureFile.path = msg.NewCapture.path;
CaptureCopied = true;
}
else if (msg.Type == TargetControlMessageType.RegisterAPI)
+14 -6
View File
@@ -268,10 +268,15 @@ namespace renderdocui.Windows.Dialogs
private void OnCapture()
{
string exe = exePath.Text;
if (!File.Exists(exe))
// for non-remote captures, check the executable locally
if (!m_Core.Renderer.IsRemoteConnected)
{
MessageBox.Show("Invalid application executable: " + exe, "Invalid executable", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
if (!File.Exists(exe))
{
MessageBox.Show("Invalid application executable: " + exe, "Invalid executable", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
string workingDir = "";
@@ -304,9 +309,6 @@ namespace renderdocui.Windows.Dialogs
private void TriggerCapture()
{
//(new LiveCapture()).Show(DockPanel);
//return;
if(InjectMode && m_InjectCallback != null)
OnInject();
@@ -538,6 +540,12 @@ namespace renderdocui.Windows.Dialogs
{
// invalid path or similar
}
// if it's a unix style path, maintain the slash type
if (Helpers.CharCount(exePath.Text, '/') > Helpers.CharCount(exePath.Text, '\\'))
{
workDirPath.Text.Replace('\\', '/');
}
}
public void UpdateGlobalHook()
+49 -71
View File
@@ -72,11 +72,11 @@ namespace renderdocui.Windows
public string api;
public DateTime timestamp;
public bool copying;
public bool saved;
public bool opened;
public string localpath;
public string path;
public bool local;
};
class ChildProcess
@@ -214,33 +214,20 @@ namespace renderdocui.Windows
DateTime timestamp = new DateTime(1970, 1, 1, 0, 0, 0);
timestamp = timestamp.AddSeconds(m_Connection.CaptureFile.timestamp).ToLocalTime();
byte[] thumb = m_Connection.CaptureFile.thumbnail;
string path = m_Connection.CaptureFile.localpath;
string path = m_Connection.CaptureFile.path;
bool local = m_Connection.CaptureFile.local;
if (path.Length == 0 || File.Exists(path))
this.BeginInvoke((MethodInvoker)delegate
{
this.BeginInvoke((MethodInvoker)delegate
{
CaptureAdded(capID, m_Connection.Target, m_Connection.API, thumb, timestamp);
if (path.Length > 0)
CaptureRetrieved(capID, path);
});
m_Connection.CaptureExists = false;
if (path.Length == 0)
m_Connection.CopyCapture(capID, m_Core.TempLogFilename("remotecopy_" + m_Connection.Target));
}
CaptureAdded(capID, m_Connection.Target, m_Connection.API, thumb, timestamp, path, local);
});
m_Connection.CaptureExists = false;
}
if (m_Connection.CaptureCopied)
{
uint capID = m_Connection.CaptureFile.ID;
string path = m_Connection.CaptureFile.localpath;
this.BeginInvoke((MethodInvoker)delegate
{
CaptureRetrieved(capID, path);
});
m_Connection.CaptureCopied = false;
string path = m_Connection.CaptureFile.path;
}
if (m_Connection.ChildAdded)
@@ -347,21 +334,8 @@ namespace renderdocui.Windows
openMenu.Enabled = openThisCaptureToolStripMenuItem.Enabled =
(captures.SelectedItems.Count == 1);
if (captures.SelectedItems.Count > 0)
{
foreach(ListViewItem i in captures.SelectedItems)
{
var log = i.Tag as CaptureLog;
if (log.copying)
{
deleteMenu.Enabled =
saveMenu.Enabled = saveThisCaptureToolStripMenuItem.Enabled =
openMenu.Enabled = openThisCaptureToolStripMenuItem.Enabled = false;
return;
}
}
}
if(captures.SelectedItems.Count == 1)
newInstanceToolStripMenuItem.Enabled = (captures.SelectedItems[0].Tag as CaptureLog).local;
}
private void captures_MouseDoubleClick(object sender, MouseEventArgs e)
@@ -378,27 +352,30 @@ namespace renderdocui.Windows
private void OpenCapture(CaptureLog log)
{
if (!log.copying)
{
m_Main.LoadLogfile(log.localpath, !log.saved);
log.opened = true;
}
m_Main.LoadLogfile(log.path, !log.saved, log.local);
log.opened = true;
}
private bool SaveCapture(CaptureLog log)
{
if (log.copying) return false;
string path = m_Main.GetSavePath();
// we copy the temp log to the desired path, but the log item remains referring to the temp path.
// This ensures that if the user deletes the saved path we can still open or re-save it.
if (path.Length > 0)
{
string localpath = log.path;
if (!log.local)
{
// copy locally first
}
try
{
File.Copy(log.localpath, path, true);
File.Copy(localpath, path, true);
log.saved = true;
log.path = localpath;
m_Core.Config.AddRecentFile(m_Core.Config.RecentLogFiles, path, 10);
m_Main.PopulateRecentFiles();
}
@@ -463,10 +440,14 @@ namespace renderdocui.Windows
{
try
{
if (log.localpath == m_Core.LogFileName)
if (log.path == m_Core.LogFileName)
{
m_Main.OwnTemporaryLog = true;
}
else
File.Delete(log.localpath);
{
m_Core.Renderer.DeleteCapture(log.path, log.local);
}
}
catch (System.Exception)
{
@@ -542,15 +523,15 @@ namespace renderdocui.Windows
if (!log.saved)
{
if (log.localpath == m_Core.LogFileName)
if (log.path == m_Core.LogFileName)
{
m_Main.OwnTemporaryLog = false;
m_Main.OwnTemporaryLog = true;
m_Main.CloseLogfile();
}
try
{
File.Delete(log.localpath);
m_Core.Renderer.DeleteCapture(log.path, log.local);
}
catch (System.Exception)
{
@@ -575,9 +556,16 @@ namespace renderdocui.Windows
var temppath = m_Core.TempLogFilename(log.exe);
if (!log.local)
{
MessageBox.Show("Can't open log in new instance with remote server in use", "Cannot open new instance",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
File.Copy(log.localpath, temppath);
File.Copy(log.path, temppath);
}
catch (System.Exception ex)
{
@@ -616,7 +604,7 @@ namespace renderdocui.Windows
}
}
private void CaptureAdded(uint ID, string executable, string api, byte[] thumbnail, DateTime timestamp)
private void CaptureAdded(uint ID, string executable, string api, byte[] thumbnail, DateTime timestamp, string path, bool local)
{
if (thumbnail == null || thumbnail.Length == 0)
{
@@ -639,32 +627,22 @@ namespace renderdocui.Windows
log.exe = executable;
log.api = api;
log.timestamp = timestamp;
log.copying = true;
log.saved = false;
log.path = path;
log.local = local;
var item = new ListViewItem(new string[] { log.exe + " (Copying)", log.api, log.timestamp.ToString() }, thumbs.Images.Count - 1);
string title = log.exe;
if (!local)
title += " (Remote)";
var item = new ListViewItem(new string[] { title, log.api, log.timestamp.ToString() }, thumbs.Images.Count - 1);
item.Tag = log;
item.SubItems[0].Font = new Font(item.SubItems[0].Font, FontStyle.Italic);
if(!local)
item.SubItems[0].Font = new Font(item.SubItems[0].Font, FontStyle.Italic);
captures.Items.Add(item);
}
private void CaptureRetrieved(uint ID, string localpath)
{
foreach (ListViewItem i in captures.Items)
{
var log = i.Tag as CaptureLog;
if (log.remoteID == ID && log.copying)
{
log.copying = false;
log.localpath = localpath;
i.SubItems[0].Text = log.exe;
i.SubItems[0].Font = new Font(i.SubItems[0].Font, FontStyle.Regular);
}
}
}
private void ConnectionClosed()
{
if (m_IgnoreThreadClosed) return;
+41 -36
View File
@@ -613,36 +613,43 @@ namespace renderdocui.Windows
#region Capture & Log Loading
private void LoadLogAsync(string filename, bool temporary)
public void LoadLogfile(string filename, bool temporary, bool local)
{
if (m_Core.LogLoading) return;
string driver = "";
bool support = StaticExports.SupportLocalReplay(filename, out driver);
Thread thread = null;
// if driver is empty something went wrong loading the log, let it be handled as usual
// below. Otherwise indicate that support is missing.
if (driver.Length > 0 && !support)
if (PromptCloseLog())
{
string remoteMessage = String.Format("This log was captured with {0} and cannot be replayed locally.\n\n", driver);
if (m_Core.LogLoading) return;
remoteMessage += "Try selecting a remote context in the status bar.";
string driver = "";
bool support = false;
MessageBox.Show(remoteMessage, "Unsupported logfile type", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
if (local)
support = StaticExports.SupportLocalReplay(filename, out driver);
Thread thread = null;
// if driver is empty something went wrong loading the log, let it be handled as usual
// below. Otherwise indicate that support is missing.
if (driver.Length > 0 && !support && local)
{
string remoteMessage = String.Format("This log was captured with {0} and cannot be replayed locally.\n\n", driver);
remoteMessage += "Try selecting a remote context in the status bar.";
MessageBox.Show(remoteMessage, "Unsupported logfile type", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
else
{
thread = Helpers.NewThread(new ThreadStart(() => m_Core.LoadLogfile(filename, temporary, local)));
}
thread.Start();
if(local)
m_Core.Config.LastLogPath = Path.GetDirectoryName(filename);
statusText.Text = "Loading " + filename + "...";
}
else
{
thread = Helpers.NewThread(new ThreadStart(() => m_Core.LoadLogfile(filename, temporary)));
}
thread.Start();
m_Core.Config.LastLogPath = Path.GetDirectoryName(filename);
statusText.Text = "Loading " + filename + "...";
}
public void PopulateRecentFiles()
@@ -713,12 +720,6 @@ namespace renderdocui.Windows
m_LiveCaptures.Remove(live);
}
public void LoadLogfile(string fn, bool temporary)
{
if (PromptCloseLog())
LoadLogAsync(fn, temporary);
}
private void OpenCaptureConfigFile(String filename, bool exe)
{
if (m_Core.CaptureDialog == null)
@@ -744,7 +745,7 @@ namespace renderdocui.Windows
{
if (Path.GetExtension(filename) == ".rdc")
{
LoadLogfile(filename, false);
LoadLogfile(filename, false, true);
}
else if (Path.GetExtension(filename) == ".cap")
{
@@ -757,7 +758,7 @@ namespace renderdocui.Windows
else
{
// not a recognised filetype, see if we can load it anyway
LoadLogfile(filename, false);
LoadLogfile(filename, false, true);
}
}
@@ -785,7 +786,7 @@ namespace renderdocui.Windows
string logfile = m_Core.TempLogFilename(Path.GetFileNameWithoutExtension(exe));
UInt32 ret = StaticExports.ExecuteAndInject(exe, workingDir, cmdLine, logfile, opts);
UInt32 ret = m_Core.Renderer.ExecuteAndInject(exe, workingDir, cmdLine, logfile, opts);
if (ret == 0)
{
@@ -794,7 +795,7 @@ namespace renderdocui.Windows
return null;
}
var live = new LiveCapture(m_Core, "", ret, this);
var live = new LiveCapture(m_Core, m_RemoteHost == null ? "" : m_RemoteHost.Hostname, ret, this);
ShowLiveCapture(live);
return live;
}
@@ -920,6 +921,8 @@ namespace renderdocui.Windows
m_Core.Renderer.DisconnectFromRemoteServer();
injectIntoProcessToolStripMenuItem.Enabled = true;
m_RemoteHost = null;
statusText.Text = "";
@@ -937,6 +940,8 @@ namespace renderdocui.Windows
// disable until checking is done
contextChooser.Enabled = false;
injectIntoProcessToolStripMenuItem.Enabled = false;
m_RemoteHost = host;
SetTitle();
@@ -1425,7 +1430,7 @@ namespace renderdocui.Windows
if(File.Exists(filename))
{
LoadLogfile(filename, false);
LoadLogfile(filename, false, true);
}
else
{