|
|
- using System;
- using NUnit.Framework.Constraints;
- using UnityEngine;
- using System.Collections.Generic;
- using Treemap;
- using UnityEditor;
- using Assets.Editor.Treemap;
- using System.Linq;
- using UnityEngine.UI;
-
- namespace MemoryProfilerWindow
- {
- public class TreeMapView
- {
- CrawledMemorySnapshot _unpackedCrawl;
- private ZoomArea _ZoomArea;
- private Dictionary<string, Group> _groups = new Dictionary<string, Group>();
- private List<Item> _items = new List<Item>();
- private List<Mesh> _cachedMeshes = new List<Mesh>();
- private Item _selectedItem;
- private Group _selectedGroup;
- private Item _mouseDownItem;
-
- MemoryProfilerWindow _hostWindow;
-
- private Vector2 mouseTreemapPosition { get { return _ZoomArea.ViewToDrawingTransformPoint(Event.current.mousePosition); } }
-
- public void Setup(MemoryProfilerWindow hostWindow, CrawledMemorySnapshot _unpackedCrawl)
- {
- this._unpackedCrawl = _unpackedCrawl;
- this._hostWindow = hostWindow;
-
- _ZoomArea = new ZoomArea(true)
- {
- vRangeMin = -110f,
- vRangeMax = 110f,
- hRangeMin = -110f,
- hRangeMax = 110f,
- hBaseRangeMin = -110f,
- vBaseRangeMin = -110f,
- hBaseRangeMax = 110f,
- vBaseRangeMax = 110f,
- shownArea = new Rect(-110f, -110f, 220f, 220f)
- };
- RefreshCaches();
- RefreshMesh();
- }
-
- public void Draw()
- {
- if (_hostWindow == null)
- return;
-
- Rect r = new Rect(0f, 25f, _hostWindow.position.width - _hostWindow._inspector.width, _hostWindow.position.height - 25f);
-
- _ZoomArea.rect = r;
- _ZoomArea.BeginViewGUI();
-
- GUI.BeginGroup(r);
- Handles.matrix = _ZoomArea.drawingToViewMatrix;
- HandleMouseClick();
- RenderTreemap();
- GUI.EndGroup();
-
- _ZoomArea.EndViewGUI();
- }
-
- private void OnHoveredGroupChanged()
- {
- RefreshCachedRects(false);
- }
-
- private void HandleMouseClick()
- {
- if ((Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseUp) && Event.current.button == 0)
- {
- if (_ZoomArea.drawRect.Contains(Event.current.mousePosition))
- {
- Group group = _groups.Values.FirstOrDefault(i => i._position.Contains(mouseTreemapPosition));
- Item item = _items.FirstOrDefault(i => i._position.Contains(mouseTreemapPosition));
-
- if (item != null && _selectedGroup == item._group)
- {
- switch (Event.current.type)
- {
- case EventType.MouseDown:
- _mouseDownItem = item;
- break;
-
- case EventType.MouseUp:
- if (_mouseDownItem == item)
- {
- _hostWindow.SelectThing(item._thingInMemory);
- Event.current.Use();
- }
- break;
- }
- }
- else if (group != null)
- {
- switch (Event.current.type)
- {
- case EventType.MouseUp:
- _hostWindow.SelectGroup(group);
- Event.current.Use();
- break;
- }
- }
- }
- }
- }
-
- public void SelectThing(ThingInMemory thing)
- {
- _selectedItem = _items.First(i => i._thingInMemory == thing);
- _selectedGroup = _selectedItem._group;
- RefreshCachedRects(false);
- }
-
- public void SelectGroup(Group group)
- {
- _selectedItem = null;
- _selectedGroup = group;
- RefreshCachedRects(false);
- }
-
- void RefreshCaches()
- {
- _items.Clear();
- _groups.Clear();
-
- foreach (ThingInMemory thingInMemory in _unpackedCrawl.allObjects)
- {
- string groupName = GetGroupName(thingInMemory);
- if (groupName.Length == 0)
- continue;
-
- if (!_groups.ContainsKey(groupName))
- {
- Group newGroup = new Group();
- newGroup._name = groupName;
- newGroup._items = new List<Item>();
- _groups.Add(groupName, newGroup);
- }
-
- Item item = new Item(thingInMemory, _groups[groupName]);
- _items.Add(item);
- _groups[groupName]._items.Add(item);
- }
-
- foreach (Group group in _groups.Values)
- {
- group._items.Sort();
- }
-
- _items.Sort();
- RefreshCachedRects(true);
- }
-
- private void RefreshCachedRects(bool fullRefresh)
- {
- Rect space = new Rect(-100f, -100f, 200f, 200f);
-
- if (fullRefresh)
- {
- List<Group> groups = _groups.Values.ToList();
- groups.Sort();
- float[] groupTotalValues = new float[groups.Count];
- for (int i = 0; i < groups.Count; i++)
- {
- groupTotalValues[i] = groups.ElementAt(i).totalMemorySize;
- }
-
- Rect[] groupRects = Utility.GetTreemapRects(groupTotalValues, space);
- for (int groupIndex = 0; groupIndex < groupRects.Length; groupIndex++)
- {
- Group group = groups[groupIndex];
- group._position = groupRects[groupIndex];
- }
- }
-
- if (_selectedGroup != null)
- {
- Rect[] rects = Utility.GetTreemapRects(_selectedGroup.memorySizes, _selectedGroup._position);
-
- for (int i = 0; i < rects.Length; i++)
- {
- _selectedGroup._items[i]._position = rects[i];
- }
- }
-
- RefreshMesh();
- }
-
- public void CleanupMeshes ()
- {
- if (_cachedMeshes == null) {
- _cachedMeshes = new List<Mesh> ();
- }
- else {
- for (int i = 0; i < _cachedMeshes.Count; i++) {
- UnityEngine.Object.DestroyImmediate (_cachedMeshes [i]);
- }
-
- _cachedMeshes.Clear ();
- }
- }
-
- private void RefreshMesh()
- {
- CleanupMeshes ();
-
- const int maxVerts = 32000;
- Vector3[] vertices = new Vector3[maxVerts];
- Color[] colors = new Color[maxVerts];
- int[] triangles = new int[maxVerts * 6 / 4];
-
- int meshItemIndex = 0;
- int totalItemIndex = 0;
-
- List<ITreemapRenderable> visible = new List<ITreemapRenderable>();
- foreach (Group group in _groups.Values)
- {
- if (group != _selectedGroup)
- {
- visible.Add(group);
- }
- else
- {
- foreach (Item item in group._items)
- {
- visible.Add(item);
- }
- }
- }
-
- foreach (ITreemapRenderable item in visible)
- {
- int index = meshItemIndex * 4;
- vertices[index++] = new Vector3(item.GetPosition().xMin, item.GetPosition().yMin, 0f);
- vertices[index++] = new Vector3(item.GetPosition().xMax, item.GetPosition().yMin, 0f);
- vertices[index++] = new Vector3(item.GetPosition().xMax, item.GetPosition().yMax, 0f);
- vertices[index++] = new Vector3(item.GetPosition().xMin, item.GetPosition().yMax, 0f);
-
- index = meshItemIndex * 4;
- var color = item.GetColor();
- if (item == _selectedItem)
- color *= 1.5f;
-
- colors[index++] = color;
- colors[index++] = color * 0.75f;
- colors[index++] = color * 0.5f;
- colors[index++] = color * 0.75f;
-
- index = meshItemIndex * 6;
- triangles[index++] = meshItemIndex * 4 + 0;
- triangles[index++] = meshItemIndex * 4 + 1;
- triangles[index++] = meshItemIndex * 4 + 3;
- triangles[index++] = meshItemIndex * 4 + 1;
- triangles[index++] = meshItemIndex * 4 + 2;
- triangles[index++] = meshItemIndex * 4 + 3;
-
- meshItemIndex++;
- totalItemIndex++;
-
- if (meshItemIndex >= maxVerts / 4 || totalItemIndex == visible.Count)
- {
- Mesh mesh = new Mesh();
- mesh.hideFlags = HideFlags.DontSaveInEditor | HideFlags.HideInHierarchy | HideFlags.NotEditable;
- mesh.vertices = vertices;
- mesh.triangles = triangles;
- mesh.colors = colors;
- _cachedMeshes.Add(mesh);
-
- vertices = new Vector3[maxVerts];
- colors = new Color[maxVerts];
- triangles = new int[maxVerts * 6 / 4];
- meshItemIndex = 0;
- }
- }
- }
-
- public void RenderTreemap()
- {
- if (_cachedMeshes == null)
- return;
-
- Material mat = (Material)EditorGUIUtility.LoadRequired("SceneView/2DHandleLines.mat");
- mat.SetPass(0);
-
- for (int i = 0; i < _cachedMeshes.Count; i++)
- {
- Graphics.DrawMeshNow(_cachedMeshes[i], Handles.matrix);
- }
- RenderLabels();
- }
-
- private void RenderLabels()
- {
- if (_groups == null)
- return;
-
- GUI.color = Color.black;
- Matrix4x4 mat = _ZoomArea.drawingToViewMatrix;
-
- foreach (Group group in _groups.Values)
- {
- if (Utility.IsInside(group._position, _ZoomArea.shownArea))
- {
- if (_selectedItem != null && _selectedItem._group == group)
- {
- RenderGroupItems(group);
- }
- else
- {
- RenderGroupLabel(group);
- }
- }
- }
-
- GUI.color = Color.white;
- }
-
- private void RenderGroupLabel(Group group)
- {
- Matrix4x4 mat = _ZoomArea.drawingToViewMatrix;
-
- Vector3 p1 = mat.MultiplyPoint(new Vector3(group._position.xMin, group._position.yMin));
- Vector3 p2 = mat.MultiplyPoint(new Vector3(group._position.xMax, group._position.yMax));
-
- if (p2.x - p1.x > 30f)
- {
- Rect rect = new Rect(p1.x, p2.y, p2.x - p1.x, p1.y - p2.y);
- GUI.Label(rect, group.GetLabel());
- }
- }
-
- private void RenderGroupItems(Group group)
- {
- Matrix4x4 mat = _ZoomArea.drawingToViewMatrix;
-
- foreach (Item item in group._items)
- {
- if (Utility.IsInside(item._position, _ZoomArea.shownArea))
- {
- Vector3 p1 = mat.MultiplyPoint(new Vector3(item._position.xMin, item._position.yMin));
- Vector3 p2 = mat.MultiplyPoint(new Vector3(item._position.xMax, item._position.yMax));
-
- if (p2.x - p1.x > 30f)
- {
- Rect rect = new Rect(p1.x, p2.y, p2.x - p1.x, p1.y - p2.y);
- string row1 = item._group._name;
- string row2 = EditorUtility.FormatBytes(item.memorySize);
- GUI.Label(rect, row1 + "\n" + row2);
- }
- }
- }
- }
-
- public string GetGroupName(ThingInMemory thing)
- {
- if (thing is NativeUnityEngineObject)
- return (thing as NativeUnityEngineObject).className ?? "MissingName";
- if (thing is ManagedObject)
- return (thing as ManagedObject).typeDescription.name;
- return thing.GetType().Name;
- }
- }
- }
|