mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 09:30:44 +00:00
905 lines
27 KiB
C#
905 lines
27 KiB
C#
/******************************************************************************
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2014 Crytek
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using WeifenLuo.WinFormsUI.Docking;
|
|
using renderdocui.Code;
|
|
using renderdoc;
|
|
using System.IO;
|
|
|
|
namespace renderdocui.Windows
|
|
{
|
|
public partial class EventBrowser : DockContent, ILogViewerForm
|
|
{
|
|
class DeferredEvent
|
|
{
|
|
public UInt32 frameID = 0;
|
|
public UInt32 eventID = 0;
|
|
|
|
public ResourceId defCtx = ResourceId.Null;
|
|
public UInt32 firstDefEv = 0;
|
|
public UInt32 lastDefEv = 0;
|
|
}
|
|
|
|
private List<TreelistView.Node> m_FrameNodes = new List<TreelistView.Node>();
|
|
|
|
private Core m_Core;
|
|
|
|
public EventBrowser(Core core)
|
|
{
|
|
InitializeComponent();
|
|
|
|
Icon = global::renderdocui.Properties.Resources.icon;
|
|
|
|
HideJumpAndFind();
|
|
|
|
m_Core = core;
|
|
|
|
DockHandler.GetPersistStringCallback = PersistString;
|
|
|
|
var col = eventView.Columns["Drawcall"]; eventView.Columns.SetVisibleIndex(col, -1);
|
|
col = eventView.Columns["Duration"]; eventView.Columns.SetVisibleIndex(col, -1);
|
|
|
|
UpdateDurationColumn();
|
|
|
|
eventView.CellPainter.CellDataConverter = DataToString;
|
|
|
|
findEventButton.Enabled = false;
|
|
jumpEventButton.Enabled = false;
|
|
timeDraws.Enabled = false;
|
|
}
|
|
|
|
public class PersistData
|
|
{
|
|
public static int currentPersistVersion = 1;
|
|
public int persistVersion = currentPersistVersion;
|
|
|
|
public struct ColumnArrangement
|
|
{
|
|
public string fieldname;
|
|
public int visibleindex;
|
|
public int width;
|
|
};
|
|
|
|
public List<ColumnArrangement> visibleColumns = new List<ColumnArrangement>();
|
|
|
|
public static PersistData GetDefaults(TreelistView.TreeListView view)
|
|
{
|
|
PersistData data = new PersistData();
|
|
|
|
foreach (var c in view.Columns)
|
|
{
|
|
ColumnArrangement a = new ColumnArrangement();
|
|
a.fieldname = c.Fieldname;
|
|
a.visibleindex = c.VisibleIndex;
|
|
a.width = c.Width;
|
|
data.visibleColumns.Add(a);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
}
|
|
|
|
public void InitFromPersistString(string str)
|
|
{
|
|
PersistData data = null;
|
|
|
|
try
|
|
{
|
|
if (str.Length > GetType().ToString().Length)
|
|
{
|
|
var reader = new StringReader(str.Substring(GetType().ToString().Length));
|
|
|
|
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(PersistData));
|
|
data = (PersistData)xs.Deserialize(reader);
|
|
|
|
reader.Close();
|
|
}
|
|
}
|
|
catch (System.Xml.XmlException)
|
|
{
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
// don't need to handle it. Leave data null and pick up defaults below
|
|
}
|
|
|
|
if (data == null || data.persistVersion != PersistData.currentPersistVersion)
|
|
{
|
|
data = PersistData.GetDefaults(eventView);
|
|
}
|
|
|
|
ApplyPersistData(data);
|
|
}
|
|
|
|
private void ApplyPersistData(PersistData data)
|
|
{
|
|
// loop twice because first time will ensure the right columns are visible but
|
|
// e.g. if the first column we grabbed should be in visibleindex 2, it would
|
|
// get shown and be forced to 0 (arbitrary example). Second pass ensures the
|
|
// order is correct
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
foreach (var c in data.visibleColumns)
|
|
{
|
|
var col = eventView.Columns[c.fieldname];
|
|
if (col == null) continue;
|
|
eventView.Columns.SetVisibleIndex(col, c.visibleindex);
|
|
|
|
if (i == 1)
|
|
col.Width = c.width;
|
|
}
|
|
}
|
|
}
|
|
|
|
private string PersistString()
|
|
{
|
|
var writer = new StringWriter();
|
|
|
|
writer.Write(GetType().ToString());
|
|
|
|
PersistData data = PersistData.GetDefaults(eventView);
|
|
|
|
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(PersistData));
|
|
xs.Serialize(writer, data);
|
|
|
|
return writer.ToString();
|
|
}
|
|
|
|
|
|
private PersistantConfig.TimeUnit m_TimeUnit = PersistantConfig.TimeUnit.Microseconds;
|
|
|
|
private void UpdateDurationColumn()
|
|
{
|
|
m_TimeUnit = m_Core.Config.EventBrowser_TimeUnit;
|
|
|
|
string durationString = PersistantConfig.UnitPrefix(m_TimeUnit);
|
|
|
|
eventView.Columns["Duration"].Caption = String.Format("Duration ({0})", durationString);
|
|
}
|
|
|
|
private string DataToString(TreelistView.TreeListColumn column, object data)
|
|
{
|
|
if (column.Fieldname == "Duration")
|
|
{
|
|
double f = (double)data;
|
|
if (f < 0.0)
|
|
return "";
|
|
|
|
if (m_Core.Config.EventBrowser_TimeUnit != m_TimeUnit)
|
|
UpdateDurationColumn();
|
|
|
|
if (m_Core.Config.EventBrowser_TimeUnit == PersistantConfig.TimeUnit.Milliseconds)
|
|
f *= 1000.0;
|
|
else if (m_Core.Config.EventBrowser_TimeUnit == PersistantConfig.TimeUnit.Microseconds)
|
|
f *= 1000000.0;
|
|
else if (m_Core.Config.EventBrowser_TimeUnit == PersistantConfig.TimeUnit.Nanoseconds)
|
|
f *= 1000000000.0;
|
|
|
|
return Formatter.Format(f);
|
|
}
|
|
|
|
return data.ToString();
|
|
}
|
|
|
|
private TreelistView.Node MakeMarker(string text)
|
|
{
|
|
return new TreelistView.Node(new object[] { "", "", text, -1.0 });
|
|
}
|
|
|
|
private TreelistView.Node MakeNode(UInt32 EID, UInt32 draw, string text, double duration)
|
|
{
|
|
return new TreelistView.Node(new object[] { EID, draw, text, duration });
|
|
}
|
|
|
|
private TreelistView.Node AddDrawcall(TreelistView.Node existing, FetchDrawcall drawcall, TreelistView.Node root)
|
|
{
|
|
if (m_Core.Config.EventBrowser_HideEmpty)
|
|
{
|
|
if ((drawcall.children == null || drawcall.children.Length == 0) && (drawcall.flags & DrawcallFlags.PushMarker) != 0)
|
|
return null;
|
|
}
|
|
|
|
UInt32 eventNum = drawcall.eventID;
|
|
double duration = drawcall.duration;
|
|
TreelistView.Node drawNode = MakeNode(eventNum, drawcall.drawcallID, drawcall.name, duration);
|
|
|
|
if (existing != null)
|
|
{
|
|
existing.SetData(drawNode.GetData());
|
|
drawNode = existing;
|
|
}
|
|
else
|
|
{
|
|
root.Nodes.Add(drawNode);
|
|
}
|
|
|
|
DeferredEvent def = new DeferredEvent();
|
|
def.frameID = m_Core.CurFrame;
|
|
def.eventID = eventNum;
|
|
|
|
if (drawcall.context != m_Core.FrameInfo[m_Core.CurFrame].immContextId)
|
|
{
|
|
def.defCtx = drawcall.context;
|
|
def.lastDefEv = drawcall.eventID;
|
|
|
|
FetchDrawcall parent = drawcall.parent;
|
|
while(!parent.name.Contains("ExecuteCommand"))
|
|
parent = parent.parent;
|
|
|
|
def.eventID = parent.eventID-1;
|
|
|
|
def.firstDefEv = parent.children[0].eventID;
|
|
if(parent.children[0].events.Length > 0)
|
|
def.firstDefEv = parent.children[0].events[0].eventID;
|
|
}
|
|
|
|
drawNode.Tag = def;
|
|
|
|
if (drawcall.children != null && drawcall.children.Length > 0)
|
|
{
|
|
for (int i = 0; i < drawcall.children.Length; i++)
|
|
{
|
|
TreelistView.Node d = drawNode.Nodes.Count > i ? drawNode.Nodes[i] : null;
|
|
|
|
AddDrawcall(d, drawcall.children[i], drawNode);
|
|
|
|
if (i > 0 && (drawcall.children[i-1].flags & DrawcallFlags.SetMarker) > 0)
|
|
{
|
|
drawNode.Nodes[drawNode.Nodes.Count - 2].Tag = drawNode.Nodes.LastNode.Tag;
|
|
}
|
|
|
|
if ((double)drawNode.Nodes[i]["Duration"] > 0.0)
|
|
drawNode["Duration"] = Math.Max(0.0, (double)drawNode["Duration"]) + (double)drawNode.Nodes[i]["Duration"];
|
|
}
|
|
|
|
bool found = false;
|
|
|
|
for (int i = drawcall.children.Length - 1; i >= 0; i--)
|
|
{
|
|
if ((drawcall.children[i].flags & DrawcallFlags.SetMarker) == 0)
|
|
{
|
|
drawNode.Tag = drawNode.Nodes[i].Tag;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!found)
|
|
drawNode.Tag = drawNode.Nodes.LastNode.Tag;
|
|
}
|
|
|
|
return drawNode;
|
|
}
|
|
|
|
private void AddFrameDrawcalls(TreelistView.Node frame, FetchDrawcall[] drawcalls)
|
|
{
|
|
eventView.BeginUpdate();
|
|
|
|
frame["Duration"] = -1.0;
|
|
|
|
DeferredEvent startEv = new DeferredEvent();
|
|
startEv.frameID = m_Core.CurFrame;
|
|
startEv.eventID = 0;
|
|
|
|
if(frame.Nodes.Count == 0)
|
|
frame.Nodes.Add(MakeNode(0, 0, "Frame Start", -1.0)).Tag = startEv;
|
|
|
|
for (int i = 0; i < drawcalls.Length; i++)
|
|
{
|
|
TreelistView.Node d = frame.Nodes.Count > (i + 1) ? frame.Nodes[i + 1] : null;
|
|
|
|
TreelistView.Node newD = AddDrawcall(d, drawcalls[i], frame);
|
|
|
|
if (newD != null)
|
|
{
|
|
d = newD;
|
|
|
|
if ((double)d["Duration"] > 0.0)
|
|
frame["Duration"] = Math.Max(0.0, (double)frame["Duration"]) + (double)d["Duration"];
|
|
}
|
|
}
|
|
|
|
frame.Tag = frame.Nodes.LastNode.Tag;
|
|
|
|
eventView.EndUpdate();
|
|
}
|
|
|
|
public void OnLogfileClosed()
|
|
{
|
|
eventView.BeginUpdate();
|
|
eventView.Nodes.Clear();
|
|
m_FrameNodes.Clear();
|
|
eventView.EndUpdate();
|
|
|
|
findEventButton.Enabled = false;
|
|
jumpEventButton.Enabled = false;
|
|
timeDraws.Enabled = false;
|
|
}
|
|
|
|
public void OnLogfileLoaded()
|
|
{
|
|
FetchFrameInfo[] frameList = m_Core.FrameInfo;
|
|
|
|
findEventButton.Enabled = true;
|
|
jumpEventButton.Enabled = true;
|
|
timeDraws.Enabled = true;
|
|
|
|
eventView.BeginUpdate();
|
|
|
|
eventView.Nodes.Clear();
|
|
|
|
m_FrameNodes.Clear();
|
|
|
|
for (int curFrame = 0; curFrame < frameList.Length; curFrame++)
|
|
{
|
|
TreelistView.Node frame = eventView.Nodes.Add(MakeMarker("Frame #" + frameList[curFrame].frameNumber.ToString()));
|
|
|
|
m_FrameNodes.Add(frame);
|
|
}
|
|
|
|
eventView.EndUpdate();
|
|
|
|
for (int curFrame = 0; curFrame < frameList.Length; curFrame++)
|
|
AddFrameDrawcalls(m_FrameNodes[curFrame], m_Core.GetDrawcalls((UInt32)curFrame));
|
|
|
|
if (frameList.Length > 0)
|
|
{
|
|
// frame 1 -> event 1
|
|
TreelistView.Node node = eventView.Nodes[0].Nodes[0];
|
|
|
|
ExpandNode(node);
|
|
|
|
DeferredEvent evt = eventView.Nodes[0].Nodes.LastNode.Tag as DeferredEvent;
|
|
|
|
m_Core.SetEventID(null, 0, evt.eventID + 1);
|
|
|
|
eventView.NodesSelection.Clear();
|
|
eventView.NodesSelection.Add(eventView.Nodes[0]);
|
|
eventView.FocusedNode = eventView.Nodes[0];
|
|
}
|
|
}
|
|
|
|
public void ExpandNode(TreelistView.Node node)
|
|
{
|
|
var n = node;
|
|
while (node != null)
|
|
{
|
|
node.Expand();
|
|
node = node.Parent;
|
|
}
|
|
eventView.EnsureVisible(n);
|
|
}
|
|
|
|
private bool SelectEvent(ref TreelistView.Node found, TreelistView.NodeCollection nodes, UInt32 frameID, UInt32 eventID)
|
|
{
|
|
foreach (var n in nodes)
|
|
{
|
|
DeferredEvent ndef = n.Tag is DeferredEvent ? n.Tag as DeferredEvent : null;
|
|
DeferredEvent fdef = found != null && found.Tag is DeferredEvent ? found.Tag as DeferredEvent : null;
|
|
|
|
if (ndef != null)
|
|
{
|
|
if (ndef.eventID >= eventID && (found == null || ndef.eventID <= fdef.eventID))
|
|
found = n;
|
|
|
|
if (ndef.eventID == eventID && n.Nodes.Count == 0)
|
|
return true;
|
|
}
|
|
|
|
if (n.Nodes.Count > 0)
|
|
{
|
|
bool exact = SelectEvent(ref found, n.Nodes, frameID, eventID);
|
|
if (exact) return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool SelectEvent(UInt32 frameID, UInt32 eventID)
|
|
{
|
|
if (eventView.Nodes.Count == 0) return false;
|
|
|
|
TreelistView.Node found = null;
|
|
SelectEvent(ref found, eventView.Nodes[0].Nodes, frameID, eventID);
|
|
if (found != null)
|
|
{
|
|
eventView.FocusedNode = found;
|
|
|
|
ExpandNode(found);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void ClearFindIcons(TreelistView.NodeCollection nodes)
|
|
{
|
|
foreach (var n in nodes)
|
|
{
|
|
n.Image = null;
|
|
|
|
if (n.Nodes.Count > 0)
|
|
{
|
|
ClearFindIcons(n.Nodes);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ClearFindIcons()
|
|
{
|
|
if (eventView.Nodes.Count > 0)
|
|
{
|
|
ClearFindIcons(eventView.Nodes[0].Nodes);
|
|
|
|
eventView.Invalidate();
|
|
}
|
|
}
|
|
|
|
private int SetFindIcons(TreelistView.NodeCollection nodes, string filter)
|
|
{
|
|
int results = 0;
|
|
|
|
foreach (var n in nodes)
|
|
{
|
|
if (n.Tag is DeferredEvent)
|
|
{
|
|
if (n["Name"].ToString().ToLowerInvariant().Contains(filter))
|
|
{
|
|
n.Image = global::renderdocui.Properties.Resources.find;
|
|
results++;
|
|
}
|
|
}
|
|
|
|
if (n.Nodes.Count > 0)
|
|
{
|
|
results += SetFindIcons(n.Nodes, filter);
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
private int SetFindIcons(string filter)
|
|
{
|
|
if(filter == "")
|
|
return 0;
|
|
|
|
return SetFindIcons(eventView.Nodes[0].Nodes, filter.ToLowerInvariant());
|
|
}
|
|
|
|
private TreelistView.Node FindNode(TreelistView.NodeCollection nodes, string filter, UInt32 after)
|
|
{
|
|
foreach (var n in nodes)
|
|
{
|
|
if (n.Tag is DeferredEvent)
|
|
{
|
|
if ((UInt32)n["EID"] > after && n["Name"].ToString().ToLowerInvariant().Contains(filter))
|
|
return n;
|
|
}
|
|
|
|
if (n.Nodes.Count > 0)
|
|
{
|
|
TreelistView.Node found = FindNode(n.Nodes, filter, after);
|
|
|
|
if (found != null)
|
|
return found;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private int FindEvent(TreelistView.NodeCollection nodes, string filter, UInt32 after, bool forward)
|
|
{
|
|
if(nodes == null) return -1;
|
|
|
|
for (int i = forward ? 0 : nodes.Count - 1;
|
|
i >= 0 && i < nodes.Count;
|
|
i += forward ? 1 : -1)
|
|
{
|
|
var n = nodes[i];
|
|
|
|
if (n.Tag is DeferredEvent)
|
|
{
|
|
DeferredEvent def = n.Tag as DeferredEvent;
|
|
|
|
bool matchesAfter = (forward && def.eventID > after) || (!forward && def.eventID < after);
|
|
|
|
if (matchesAfter && n["Name"].ToString().ToLowerInvariant().Contains(filter))
|
|
return (int)def.eventID;
|
|
}
|
|
|
|
if (n.Nodes.Count > 0)
|
|
{
|
|
int found = FindEvent(n.Nodes, filter, after, forward);
|
|
|
|
if (found > 0)
|
|
return found;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
private int FindEvent(string filter, UInt32 after, bool forward)
|
|
{
|
|
if (eventView.Nodes.Count == 0)
|
|
return 0;
|
|
|
|
return FindEvent(eventView.Nodes[0].Nodes, filter.ToLowerInvariant(), after, forward);
|
|
}
|
|
|
|
public void OnEventSelected(UInt32 frameID, UInt32 eventID)
|
|
{
|
|
SelectEvent(frameID, eventID);
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
private void eventView_AfterSelect(object sender, TreeViewEventArgs e)
|
|
{
|
|
if (eventView.SelectedNode.Tag != null)
|
|
{
|
|
DeferredEvent def = eventView.SelectedNode.Tag as DeferredEvent;
|
|
|
|
if (def.defCtx != ResourceId.Null)
|
|
m_Core.SetContextFilter(this, 0, def.eventID, def.defCtx, def.firstDefEv, def.lastDefEv);
|
|
else
|
|
m_Core.SetEventID(this, 0, def.eventID);
|
|
}
|
|
}
|
|
|
|
private void EventBrowser_Shown(object sender, EventArgs e)
|
|
{
|
|
if (m_Core.LogLoaded)
|
|
OnLogfileLoaded();
|
|
}
|
|
|
|
private void ShowJump()
|
|
{
|
|
HideJumpAndFind();
|
|
|
|
jumpStrip.Visible = true;
|
|
findStrip.Visible = false;
|
|
|
|
jumpToEID.Text = "";
|
|
jumpToEID.Focus();
|
|
}
|
|
|
|
private void ShowFind()
|
|
{
|
|
HideJumpAndFind();
|
|
|
|
jumpStrip.Visible = false;
|
|
findStrip.Visible = true;
|
|
|
|
findEvent.Text = "";
|
|
findEvent.Focus();
|
|
findEvent.BackColor = SystemColors.Window;
|
|
}
|
|
|
|
private void HideJumpAndFind()
|
|
{
|
|
jumpStrip.Visible = false;
|
|
|
|
if (findEvent.Text == "")
|
|
{
|
|
findStrip.Visible = false;
|
|
|
|
ClearFindIcons();
|
|
}
|
|
}
|
|
|
|
private void eventView_KeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.KeyCode == Keys.G && e.Control && m_Core.LogLoaded)
|
|
{
|
|
ShowJump();
|
|
}
|
|
if (e.KeyCode == Keys.F && e.Control && m_Core.LogLoaded)
|
|
{
|
|
ShowFind();
|
|
}
|
|
if (e.KeyCode == Keys.T && e.Control && m_Core.LogLoaded)
|
|
{
|
|
TimeDrawcalls();
|
|
}
|
|
if (e.KeyCode == Keys.C && e.Control)
|
|
{
|
|
string text = "";
|
|
for(int i=0; i < eventView.FocusedNode.Count; i++)
|
|
{
|
|
text += DataToString(eventView.Columns[i], eventView.FocusedNode[i]) + " ";
|
|
}
|
|
text += Environment.NewLine;
|
|
|
|
Clipboard.SetText(text);
|
|
}
|
|
}
|
|
|
|
private void SelectColumns()
|
|
{
|
|
var columns = new Dictionary<string, bool>();
|
|
foreach (var c in eventView.Columns)
|
|
columns.Add(c.Fieldname, c.VisibleIndex >= 0);
|
|
|
|
var cs = new Dialogs.ColumnSelector(columns, "Name");
|
|
var result = cs.ShowDialog();
|
|
|
|
if (result == DialogResult.OK)
|
|
{
|
|
columns = cs.GetColumnValues();
|
|
|
|
foreach (var c in columns)
|
|
{
|
|
var col = eventView.Columns[c.Key];
|
|
|
|
if (col == null) continue;
|
|
|
|
if (!c.Value && col.VisibleIndex >= 0)
|
|
eventView.Columns.SetVisibleIndex(col, -1);
|
|
else if (c.Value && col.VisibleIndex < 0)
|
|
eventView.Columns.SetVisibleIndex(col, eventView.Columns.VisibleColumns.Length);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void TimeDrawcalls()
|
|
{
|
|
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
|
|
{
|
|
m_Core.TimeDrawcalls(r);
|
|
|
|
BeginInvoke((MethodInvoker)delegate
|
|
{
|
|
var col = eventView.Columns["Duration"];
|
|
if (col.VisibleIndex == -1)
|
|
{
|
|
eventView.Columns.SetVisibleIndex(col, eventView.Columns.VisibleColumns.Length);
|
|
}
|
|
|
|
for (int curFrame = 0; curFrame < m_FrameNodes.Count; curFrame++)
|
|
AddFrameDrawcalls(m_FrameNodes[curFrame], m_Core.GetDrawcalls((UInt32)curFrame));
|
|
});
|
|
});
|
|
}
|
|
private void jumpFind_Leave(object sender, EventArgs e)
|
|
{
|
|
HideJumpAndFind();
|
|
}
|
|
|
|
private void jumpToEID_TextChanged(object sender, EventArgs e)
|
|
{
|
|
/*
|
|
UInt32 eid = 0;
|
|
if (UInt32.TryParse(jumpToEID.Text, out eid))
|
|
{
|
|
SelectEvent(0, eid);
|
|
}
|
|
*/
|
|
}
|
|
|
|
private void findEvent_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (findEvent.Text != "")
|
|
{
|
|
findHighlight.Enabled = false;
|
|
findHighlight.Enabled = true;
|
|
}
|
|
else
|
|
{
|
|
findHighlight.Enabled = false;
|
|
|
|
findEvent.BackColor = SystemColors.Window;
|
|
ClearFindIcons();
|
|
}
|
|
}
|
|
|
|
private void findHighlight_Tick(object sender, EventArgs e)
|
|
{
|
|
if (findEvent.Text == "")
|
|
{
|
|
findEvent.BackColor = SystemColors.Window;
|
|
ClearFindIcons();
|
|
}
|
|
|
|
ClearFindIcons();
|
|
|
|
int results = SetFindIcons(findEvent.Text);
|
|
|
|
if (results > 0)
|
|
findEvent.BackColor = SystemColors.Window;
|
|
else
|
|
findEvent.BackColor = Color.Red;
|
|
|
|
findHighlight.Enabled = false;
|
|
}
|
|
|
|
private void findEvent_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
// escape key
|
|
if (e.KeyChar == '\0')
|
|
{
|
|
findHighlight.Enabled = false;
|
|
findEvent.Text = "";
|
|
|
|
HideJumpAndFind();
|
|
|
|
eventView.Focus();
|
|
|
|
e.Handled = true;
|
|
}
|
|
if (e.KeyChar == '\n' || e.KeyChar == '\r')
|
|
{
|
|
if (findHighlight.Enabled)
|
|
{
|
|
findHighlight.Enabled = false;
|
|
findHighlight_Tick(sender, null);
|
|
}
|
|
|
|
if (findEvent.Text != "")
|
|
{
|
|
Find(true);
|
|
}
|
|
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
|
|
private void jumpToEID_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
// escape key
|
|
if (e.KeyChar == '\0')
|
|
{
|
|
HideJumpAndFind();
|
|
|
|
eventView.Focus();
|
|
|
|
e.Handled = true;
|
|
}
|
|
if (e.KeyChar == '\n' || e.KeyChar == '\r')
|
|
{
|
|
UInt32 eid = 0;
|
|
if (UInt32.TryParse(jumpToEID.Text, out eid))
|
|
{
|
|
SelectEvent(0, eid);
|
|
}
|
|
|
|
//HideJumpAndFind();
|
|
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
|
|
private void closeFind_Click(object sender, EventArgs e)
|
|
{
|
|
findEvent.Text = "";
|
|
|
|
HideJumpAndFind();
|
|
|
|
eventView.Focus();
|
|
}
|
|
|
|
private void EventBrowser_Leave(object sender, EventArgs e)
|
|
{
|
|
HideJumpAndFind();
|
|
}
|
|
|
|
private void findNext_Click(object sender, EventArgs e)
|
|
{
|
|
Find(true);
|
|
}
|
|
|
|
private void findPrev_Click(object sender, EventArgs e)
|
|
{
|
|
Find(false);
|
|
}
|
|
|
|
private void Find(bool forward)
|
|
{
|
|
if(findEvent.Text == "")
|
|
return;
|
|
|
|
UInt32 curEID = m_Core.CurEvent;
|
|
if (eventView.SelectedNode != null && eventView.Tag is DeferredEvent)
|
|
curEID = (eventView.Tag as DeferredEvent).eventID;
|
|
|
|
int eid = FindEvent(findEvent.Text, curEID, forward);
|
|
if (eid >= 0)
|
|
{
|
|
SelectEvent(0, (UInt32)eid);
|
|
findEvent.BackColor = SystemColors.Window;
|
|
}
|
|
else // if(WrapSearch)
|
|
{
|
|
eid = FindEvent(findEvent.Text, forward ? 0 : UInt32.MaxValue, forward);
|
|
if (eid >= 0)
|
|
{
|
|
SelectEvent(0, (UInt32)eid);
|
|
findEvent.BackColor = SystemColors.Window;
|
|
}
|
|
else
|
|
{
|
|
findEvent.BackColor = Color.Red;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void findEventButton_Click(object sender, EventArgs e)
|
|
{
|
|
bool show = !findStrip.Visible;
|
|
|
|
HideJumpAndFind();
|
|
|
|
eventView.Focus();
|
|
|
|
if (show)
|
|
ShowFind();
|
|
}
|
|
|
|
private void jumpEventButton_Click(object sender, EventArgs e)
|
|
{
|
|
bool show = !jumpStrip.Visible;
|
|
|
|
HideJumpAndFind();
|
|
|
|
eventView.Focus();
|
|
|
|
if (show)
|
|
ShowJump();
|
|
}
|
|
|
|
private void timeDraws_Click(object sender, EventArgs e)
|
|
{
|
|
TimeDrawcalls();
|
|
}
|
|
|
|
private void selectColumnsButton_Click(object sender, EventArgs e)
|
|
{
|
|
SelectColumns();
|
|
}
|
|
|
|
private void selectVisibleColumnsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
SelectColumns();
|
|
}
|
|
|
|
private void EventBrowser_FormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
m_Core.RemoveLogViewer(this);
|
|
}
|
|
}
|
|
}
|