[
  {
    "path": "Editor/Analyzer/AnalyzeToTextbaseFileBase.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n\n\n    public abstract class AnalyzeToTextbaseFileBase : IAnalyzeFileWriter\n    {\n        protected ProfilerLogFormat logFormat\n        {\n            get; private set;\n        }\n        protected uint logVersion\n        {\n            get; private set;\n        }\n        protected ushort logPlatform\n        {\n            get; private set;\n        }\n\n        protected abstract string FooterName\n        {\n            get;\n        }\n        protected string unityVersion\n        {\n            get; private set;\n        }\n\n        public void SetInfo(ProfilerLogFormat format, string unityVer, uint dataversion, ushort platform)\n        {\n            this.logFormat = format;\n            this.logVersion = dataversion;\n            this.logPlatform = platform;\n            this.unityVersion = unityVer;\n        }\n\n        public abstract void CollectData(ProfilerFrameData frameData);\n\n        protected abstract string GetResultText();\n\n        public void WriteResultFile(string logfile, string outputpath)\n        {\n            try\n            {\n                var path = System.IO.Path.Combine(outputpath, logfile.Replace(\".\", \"_\") + this.FooterName);\n                string result = GetResultText();\n                System.IO.File.WriteAllText(path, result);\n            }\n            catch (System.Exception e)\n            {\n                ProfilerLogUtil.logErrorException(e);\n            }\n        }\n\n        public void SetFileInfo(string logfile, string outputpath)\n        {\n\n        }\n    }\n}"
  },
  {
    "path": "Editor/Analyzer/AnalyzeToTextbaseFileBase.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 55c111e5c73e93e45a21a05c4e5109db\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/AnalyzerUtil.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class AnalyzerUtil\n    {\n        public static List<IAnalyzeFileWriter> CreateAnalyzerInterfaceObjects()\n        {\n            var types = GetInterfaceType<IAnalyzeFileWriter>();\n            return CreateInstanciateObjects<IAnalyzeFileWriter>(types);\n        }\n\n        private static List<T> CreateInstanciateObjects<T>(List<System.Type> types) where T : class\n        {\n            List<T> ret = new List<T>();\n            foreach (var t in types)\n            {\n                if (t.IsAbstract) { continue; }\n                var inst = Activator.CreateInstance(t) as T;\n                ret.Add(inst);\n            }\n            return ret;\n        }\n\n        public static List<System.Type> GetInterfaceType<T>()\n        {\n            List<System.Type> ret = new List<Type>();\n            var domain = System.AppDomain.CurrentDomain;\n            var assemblies = domain.GetAssemblies();\n            foreach (var assembly in assemblies)\n            {\n                var types = assembly.GetTypes();\n                foreach (var type in types)\n                {\n                    var interfaces = type.GetInterfaces();\n                    if (interfaces == null)\n                    {\n                        continue;\n                    }\n                    foreach (var interfacetype in interfaces)\n                    {\n                        if (interfacetype == typeof(T) && !type.IsAbstract)\n                        {\n                            ret.Add(type);\n                        }\n                    }\n                }\n            }\n            return ret;\n        }\n\n    }\n}"
  },
  {
    "path": "Editor/Analyzer/AnalyzerUtil.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c4b017d20dfef334383db409d73c50ab\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/CsvStringGenerator.cs",
    "content": "﻿using System.Text;\n\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class CsvStringGenerator\n    {\n        private StringBuilder stringBuilder;\n        public CsvStringGenerator()\n        {\n            stringBuilder = new StringBuilder(1024 * 1024);\n        }\n        public CsvStringGenerator(StringBuilder sb)\n        {\n            stringBuilder = sb;\n        }\n        public CsvStringGenerator AppendColumn(string val)\n        {\n            if( val == null) { val = \"\"; }\n            if (val.Contains(\",\")) {\n                val = val.Replace(',', '.');\n            }\n            if (val.Contains(\"\\n\"))\n            {\n                val = val.Replace('\\n', ' ');\n            }\n            stringBuilder.Append(val).Append(',');\n            return this;\n        }\n        public CsvStringGenerator AppendColumn(string val,int idx,int length)\n        {\n            if (val == null)\n            {\n                stringBuilder.Append(\",\");\n                return this;\n            }\n            if (val.Contains(\",\") )\n            {\n                val = val.Replace(',', '.');\n            }\n            if (val.Contains(\"\\n\"))\n            {\n                val = val.Replace('\\n', ' ');\n            }\n            else\n            {\n                stringBuilder.Append(val, idx, length).Append(',');\n            }\n            return this;\n        }\n        public CsvStringGenerator AppendColumn(int val)\n        {\n            stringBuilder.Append(val).Append(',');\n            return this;\n        }\n        public CsvStringGenerator AppendColumn(bool val)\n        {\n            stringBuilder.Append(val).Append(',');\n            return this;\n        }\n        public CsvStringGenerator AppendColumn(float val)\n        {\n            stringBuilder.Append(val).Append(',');\n            return this;\n        }\n        public CsvStringGenerator AppendColumn(ulong val)\n        {\n            stringBuilder.Append(val).Append(',');\n            return this;\n        }\n        public CsvStringGenerator AppendColumnAsAddr(ulong val)\n        {\n            stringBuilder.Append(\"0x\");\n            AppendAddrStr(stringBuilder, val,16).Append(',');\n            return this;\n        }\n        public CsvStringGenerator NextRow()\n        {\n            stringBuilder.Append(\"\\n\");\n            return this;\n        }\n\n        public override string ToString()\n        {\n            return stringBuilder.ToString();\n        }\n\n        private static char[] addrChars = new char[] {\n            '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'\n        };\n\n        // AppendFormat(\"0x{0,0:X16}\", val) <- allocate a lot of managed memory...\n        public static StringBuilder AppendAddrStr(StringBuilder sb,ulong val,int num) {\n            for (int i = num - 1; i >= 0; --i )\n            {\n                ulong masked = (val >> (i*4) )& 0xf;\n                sb.Append(addrChars[masked]);\n            }\n            return sb;\n        }\n    }\n}"
  },
  {
    "path": "Editor/Analyzer/CsvStringGenerator.cs.meta",
    "content": "fileFormatVersion: 2\nguid: dc945cd84f5e43148bc02deadfd310b2\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/IAnalyzeFileWriter.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n    public enum ProfilerLogFormat\n    {\n        TypeData,\n        TypeRaw,\n    }\n\n    public interface IAnalyzeFileWriter\n    {\n\n        void SetFileInfo(string logfilename, string outputpath);\n        void SetInfo(ProfilerLogFormat logformat,string unityVersion, uint dataversion, ushort platform);\n\n        void CollectData(ProfilerFrameData frameData);\n\n        void WriteResultFile(string logfilaneme,string outputpath);\n\n\n    }\n}"
  },
  {
    "path": "Editor/Analyzer/IAnalyzeFileWriter.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d90901940130ecf48a5862025c483e10\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/EngineFileOperateAnalyzeToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Text;\nusing UnityEngine.Profiling;\nusing UTJ.ProfilerReader.BinaryData;\n\nusing UTJ.ProfilerReader.BinaryData.Stats;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n    public class EngineFileOperateAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n        struct FileEvent\n        {\n            public string thread;\n\n            public string eventStr;\n\n            public int frameIdx;\n            public string file;\n            public ulong size;\n            public long seekOffset;\n            public int param;\n\n            public ulong startTime;\n            public float tm;\n        }\n\n        private List<FileEvent> fileEvents = new List<FileEvent>(2048);\n        \n\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            if( frameData == null )\n            {\n                return;\n            }\n\n\n            HashSet<ProfilerSample> doneList = new HashSet<ProfilerSample>();\n            foreach( var thread in frameData.m_ThreadData)\n            {\n                if(thread.m_AllSamples == null) { continue; }\n                foreach( var sample in thread.m_AllSamples)\n                {\n                    if (!sample.sampleName.StartsWith(\"File.\")) { continue; }\n\n                    if (sample.sampleName == \"File.Open\")\n                    {\n                        AddFileOpenCloseData(frameData.frameIndex, thread, sample);\n                    }\n                    else if (sample.sampleName == \"File.Read\")\n                    {\n                        AddFileReadData(frameData.frameIndex, thread, sample);\n                    }\n                    else if (sample.sampleName == \"File.Seek\")\n                    {\n                        AddFileSeekData(frameData.frameIndex, thread, sample);\n                    }\n                    else if (sample.sampleName == \"File.Close\")\n                    {\n                        AddFileOpenCloseData(frameData.frameIndex, thread, sample);\n                    }\n                }\n            }\n        }\n\n        private void SetupInfo(ref FileEvent evt,int idx, ThreadData thread, ProfilerSample sample)\n        {\n            evt.frameIdx = idx;\n            evt.thread = thread.FullName;\n            evt.startTime = sample.startTimeUS;\n            evt.tm = sample.selfTimeUs / 1000.0f;\n            evt.eventStr = sample.sampleName;\n        }\n\n        private void AddFileOpenCloseData(int idx, ThreadData thread, ProfilerSample sample)\n        {\n            FileEvent evt = new FileEvent();\n            SetupInfo(ref evt, idx, thread, sample);\n\n            var metaData = sample.metadataValues;\n            if (metaData != null)\n            {\n                try\n                {\n                    if (metaData.Count > 0)\n                    {\n                        evt.file = metaData[0].convertedObject.ToString();\n                    }\n                }\n                catch (System.Exception e)\n                {\n                    ProfilerLogUtil.logErrorException(e);\n                }\n            }\n\n            fileEvents.Add(evt);\n        }\n\n\n        private void AddFileSeekData(int idx, ThreadData thread, ProfilerSample sample)\n        {\n            FileEvent evt = new FileEvent();\n            SetupInfo(ref evt, idx, thread, sample);\n\n            var metaData = sample.metadataValues;\n            if (metaData != null)\n            {\n                try\n                {\n                    if (metaData.Count > 0)\n                    {\n                        evt.file = metaData[0].convertedObject.ToString();\n                    }\n                    if (metaData.Count > 1)\n                    {\n                        evt.seekOffset = (long)metaData[1].convertedObject;\n                    }\n                    if (metaData.Count > 2)\n                    {\n                        evt.param = (int)metaData[2].convertedObject;\n                    }\n                }\n                catch (System.Exception e)\n                {\n                    ProfilerLogUtil.logErrorException(e);\n                }\n            }\n\n            fileEvents.Add(evt);\n        }\n\n        private void AddFileReadData(int idx ,ThreadData thread, ProfilerSample sample)\n        {\n            FileEvent evt = new FileEvent();\n            SetupInfo(ref evt, idx, thread, sample);\n\n            var metaData = sample.metadataValues;\n            if (metaData != null )\n            {\n                try\n                {\n                    if (metaData.Count > 0)\n                    {\n                        evt.file = metaData[0].convertedObject.ToString();\n                    }\n                    if (metaData.Count > 1)\n                    {\n                        evt.param = (int)metaData[1].convertedObject;\n                    }\n                    if (metaData.Count > 2)\n                    {\n                        evt.size = (ulong)metaData[2].convertedObject;\n                    }\n                }catch(System.Exception e)\n                {\n                    ProfilerLogUtil.logErrorException(e);\n                }\n            }\n\n            fileEvents.Add(evt);\n        }\n\n\n\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            AppendHeaderToStringBuilder(csvStringGenerator);\n\n            fileEvents.Sort((a, b) =>\n            {\n                if( a.startTime > b.startTime)\n                {\n                    return 1;\n                }\n                else if (a.startTime < b.startTime)\n                {\n                    return -1;\n                }\n                return 0;\n\n            });\n\n            foreach (var evt in fileEvents)\n            {\n                int filePathIdx = 0;\n                int length = 0;\n                if (evt.file != null)\n                {\n                    filePathIdx = evt.file.LastIndexOf('/') +1;\n                    length = evt.file.Length;\n                }\n\n                csvStringGenerator.AppendColumn(evt.frameIdx);\n                csvStringGenerator.AppendColumn(evt.file, filePathIdx, length - filePathIdx);\n                csvStringGenerator.AppendColumn(evt.eventStr);\n                csvStringGenerator.AppendColumn(evt.thread);\n                csvStringGenerator.AppendColumn(evt.param);\n                csvStringGenerator.AppendColumn(evt.size);\n                csvStringGenerator.AppendColumn(evt.seekOffset);\n                csvStringGenerator.AppendColumn(evt.tm);\n                csvStringGenerator.AppendColumn(evt.file);\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n        private void AppendHeaderToStringBuilder(CsvStringGenerator csvStringGenerator)\n        {\n\n            csvStringGenerator.AppendColumn(\"frameIdx\");\n            csvStringGenerator.AppendColumn(\"file\");\n            csvStringGenerator.AppendColumn(\"event\");\n            csvStringGenerator.AppendColumn(\"thread\");\n            csvStringGenerator.AppendColumn(\"param\");\n            csvStringGenerator.AppendColumn(\"size\");\n            csvStringGenerator.AppendColumn(\"seekOffset\");\n            csvStringGenerator.AppendColumn(\"execTime\");\n            csvStringGenerator.AppendColumn(\"fullPath\");\n            csvStringGenerator.NextRow();\n\n        }\n\n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_engine_file_operate.csv\";\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Editor/Analyzer/Impl/EngineFileOperateAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e15215876c0578b4aa9d055d04534599\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/GCAnalyzeToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Text;\nusing UnityEngine.Profiling;\nusing UTJ.ProfilerReader.BinaryData;\n\nusing UTJ.ProfilerReader.BinaryData.Stats;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n    public class GCAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n\n        class SampleKey : System.IEquatable<SampleKey>\n        {\n            public string threadName;\n            public string methodName;\n            public string fullMethodName;\n\n            public override int GetHashCode()\n            {\n                return threadName.GetHashCode()+ methodName.GetHashCode() ;\n            }\n            public bool Equals(SampleKey other)\n            {\n                return ((other.threadName == this.threadName) && (other.fullMethodName == this.fullMethodName));\n            }\n\n            public SampleKey(string th,string method,string fullMethod)\n            {\n                threadName = th;\n                methodName = method;\n                fullMethodName = fullMethod;\n            }\n        }\n        \n        class GcInfo\n        {\n            public uint allocNum;\n            public ulong allocAll;\n            public uint allocMax = uint.MinValue;\n            public uint allocMin = uint.MaxValue;\n        }\n\n        private Dictionary<SampleKey, GcInfo> gcDitionary = new Dictionary<SampleKey, GcInfo>();\n\n        private void AddData(string threadName,ProfilerSample sample,uint gcAlloc)\n        {\n            var key = new SampleKey(threadName,sample.sampleName, sample.fullSampleName);\n            GcInfo data;\n            if (!gcDitionary.TryGetValue(key,out data))\n            {\n                data = new GcInfo();\n                gcDitionary.Add(key, data);\n            }\n            data.allocAll += gcAlloc;\n            data.allocNum ++;\n            data.allocMin = ProfilerLogUtil.Min(data.allocMin, gcAlloc);\n            data.allocMax = ProfilerLogUtil.Max(data.allocMax, gcAlloc);\n        }\n\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            if( frameData == null )\n            {\n                return;\n            }\n\n\n            HashSet<ProfilerSample> doneList = new HashSet<ProfilerSample>();\n            foreach( var thread in frameData.m_ThreadData)\n            {\n                if(thread.m_AllSamples == null) { continue; }\n                foreach( var sample in thread.m_AllSamples)\n                {\n                    if(sample != null && sample.parent != null &&  sample.sampleName == \"GC.Alloc\")\n                    {\n                        var parent = sample.parent;\n                        if (!doneList.Contains(parent))\n                        {\n                            AddData(thread.FullName, parent, parent.GetSelfChildGcAlloc());\n                            doneList.Add(parent);\n                        }\n                    }\n                }\n            }\n        }\n\n\n\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            AppendHeaderToStringBuilder(csvStringGenerator);\n            foreach( var kvs in gcDitionary)\n            {\n                csvStringGenerator.AppendColumn(kvs.Key.threadName);\n                csvStringGenerator.AppendColumn(kvs.Key.methodName);\n                csvStringGenerator.AppendColumn(kvs.Key.fullMethodName);\n                csvStringGenerator.AppendColumn(kvs.Value.allocNum);\n                csvStringGenerator.AppendColumn(kvs.Value.allocAll);\n                csvStringGenerator.AppendColumn(kvs.Value.allocAll / kvs.Value.allocNum);\n                csvStringGenerator.AppendColumn(kvs.Value.allocMin);\n                csvStringGenerator.AppendColumn(kvs.Value.allocMax);\n                csvStringGenerator.NextRow();\n            }\n            return csvStringGenerator.ToString();\n        }\n        private void AppendHeaderToStringBuilder(CsvStringGenerator csvStringGenerator)\n        {\n            csvStringGenerator.AppendColumn(\"thread\");\n            // Total\n            csvStringGenerator.AppendColumn(\"SampleName\");\n            csvStringGenerator.AppendColumn(\"FullName\");\n            csvStringGenerator.AppendColumn(\"calls\");\n            csvStringGenerator.AppendColumn(\"all(byte)\");\n            csvStringGenerator.AppendColumn(\"average(byte)\");\n            csvStringGenerator.AppendColumn(\"min(byte)\");\n            csvStringGenerator.AppendColumn(\"max(byte)\");\n            csvStringGenerator.NextRow();\n\n        }\n\n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_gc_result.csv\";\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Editor/Analyzer/Impl/GCAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 95d7f661b5a908c4ea5067c04e49ef60\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/GcCallStackInfoAnalyzeToFile.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Diagnostics;\nusing System.Text;\nusing UTJ.ProfilerReader.BinaryData;\nusing UnityEngine.Profiling;\n\nusing UTJ.ProfilerReader.BinaryData.Stats;\nusing UTJ.ProfilerReader.RawData.Protocol;\nusing UnityEngine.Playables;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n    public class GcCallStackInfoAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n        struct SampleKey : System.IEquatable<SampleKey>\n        {\n            public string threadName;\n            public string methodName;\n            public string fullMethodName;\n            public string callStackName;\n            private int hashCodeCache;\n\n            public override int GetHashCode()\n            {\n                return this.hashCodeCache;\n            }\n            public bool Equals(SampleKey other)\n            {\n                return (\n                    (other.callStackName == this.callStackName) &&\n                    (other.fullMethodName == this.fullMethodName) &&\n                    (other.threadName == this.threadName) );\n            }\n\n            public SampleKey(string th,string method,string fullMethod,string callStack)\n            {\n                threadName = th;\n                methodName = method;\n                fullMethodName = fullMethod;\n                callStackName = callStack;\n                this.hashCodeCache = threadName.GetHashCode() + fullMethodName.GetHashCode();\n            }\n        }\n        \n        class GcInfo\n        {\n            public uint allocNum;\n            public ulong allocAll;\n            public uint allocMax = uint.MinValue;\n            public uint allocMin = uint.MaxValue;\n        }\n\n\n#if UTJ_CHECK\n        private static readonly CustomSampler _collectDataSampler = CustomSampler.Create(\"GcCallStackInfoAnalyzeToFile.CollectData\");\n        private static readonly CustomSampler _addDataSampler = CustomSampler.Create(\"GcCallStackInfoAnalyzeToFile.AddData\");\n        private static readonly CustomSampler _callStackSampler = CustomSampler.Create(\"GcCallStackInfoAnalyzeToFile.GetCallStack\");\n        private static readonly CustomSampler _gcAllocGetSampler = CustomSampler.Create(\"GcCallStackInfoAnalyzeToFile.GetSelfChildGcAlloc\");\n#endif\n\n\n        private Dictionary<SampleKey, GcInfo> gcDitionary = new Dictionary<SampleKey, GcInfo>();\n        private StringBuilder stringBuilder = new StringBuilder(1024);\n\n        private void AddData(string threadName,ProfilerSample sample,string callstack,uint gcAlloc)\n        {\n#if UTJ_CHECK\n            using (new ProfilingScope(_addDataSampler))\n#endif\n            {\n                var key = new SampleKey(threadName, sample.sampleName, sample.fullSampleName, callstack);\n                GcInfo data;\n                if (!gcDitionary.TryGetValue(key, out data))\n                {\n                    data = new GcInfo();\n                    gcDitionary.Add(key, data);\n                }\n                data.allocAll += gcAlloc;\n                data.allocNum++;\n                data.allocMin = ProfilerLogUtil.Min(data.allocMin, gcAlloc);\n                data.allocMax = ProfilerLogUtil.Max(data.allocMax, gcAlloc);\n            }\n        }\n\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n#if UTJ_CHECK\n            using (new ProfilingScope(_collectDataSampler))\n#endif\n            {\n                if (frameData == null)\n                {\n                    return;\n                }\n\n                FindGCAllocMarkerId(frameData);\n\n                if (useMakerId)\n                {\n                    foreach (var thread in frameData.m_ThreadData)\n                    {\n                        if (thread.m_AllSamples == null) { continue; }\n                        foreach (var sample in thread.m_AllSamples)\n                        {\n                            if (sample != null && sample.parent != null &&\n                                sample.makerId == this.gcAllocMakerId)\n                            {\n                                uint selfGcAlloc = 0;\n                                var parent = sample.parent;\n#if UTJ_CHECK\n                                using (new ProfilingScope(_gcAllocGetSampler))\n#endif\n                                {\n                                    selfGcAlloc = sample.currenGcAlloc;\n                                }\n                                AddData(thread.FullName, parent, GetCallStackInfo(frameData, sample),\n                                    selfGcAlloc);\n                            }\n                        }\n\n                    }\n                }\n                else\n                {\n                    foreach (var thread in frameData.m_ThreadData)\n                    {\n                        if (thread.m_AllSamples == null) { continue; }\n                        foreach (var sample in thread.m_AllSamples)\n                        {\n                            if (sample != null && sample.parent != null &&\n                                sample.sampleName == \"GC.Alloc\")\n                            {\n                                var parent = sample.parent;\n                                AddData(thread.FullName, parent, GetCallStackInfo(frameData, sample),\n                                    sample.currenGcAlloc);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        private bool useMakerId = false;\n        private bool foundMakerId = false;\n        private uint gcAllocMakerId = 0xFFFFFFFF;\n\n        private void FindGCAllocMarkerId(ProfilerFrameData frameData)\n        {\n            if (foundMakerId) { return; }\n            foreach (var thread in frameData.m_ThreadData)\n            {\n                if (thread.m_AllSamples == null) { continue; }\n                foreach (var sample in thread.m_AllSamples)\n                {\n                    if (sample != null && sample.parent != null && \n                        sample.sampleName == \"GC.Alloc\")\n                    {\n                        gcAllocMakerId = sample.makerId;\n                        foundMakerId = true;\n                        if(gcAllocMakerId != 0 && gcAllocMakerId != 0xFFFFFFFF)\n                        {\n                            useMakerId = true;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n\n        private string GetCallStackInfo( ProfilerFrameData frameData,ProfilerSample profilerSample)\n        {\n#if UTJ_CHECK\n            using (new ProfilingScope(_callStackSampler))\n#endif\n            {\n\n                if (profilerSample == null) { return \"\"; }\n                var callStackInfo = profilerSample.callStackInfo;\n                if (callStackInfo == null)\n                {\n                    return \"\";\n                }\n                stringBuilder.Length = 0;\n\n                int length = callStackInfo.stack.Length;\n                bool isAlreadyAdd = false;\n                for (int i = length - 1; i >= 0; --i)\n                {\n                    var info = frameData.FindJitInfoFromAddr(callStackInfo.stack[i]);\n                    if (info == null) { continue; }\n                    if (isAlreadyAdd)\n                    {\n                        stringBuilder.Append(\"->\");\n                    }\n                    stringBuilder.Append(\"[\");\n                    CsvStringGenerator.AppendAddrStr(stringBuilder, info.codeAddr, 16).Append(\"]\");\n                    stringBuilder.Append(info.name);\n                    isAlreadyAdd = true;\n                }\n                return stringBuilder.ToString();\n            }\n        }\n\n\n\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            AppendHeaderToStringBuilder(csvStringGenerator);\n            foreach( var kvs in gcDitionary)\n            {\n                csvStringGenerator.AppendColumn(kvs.Key.threadName);\n                csvStringGenerator.AppendColumn(kvs.Key.methodName);\n                csvStringGenerator.AppendColumn(kvs.Key.fullMethodName);\n                csvStringGenerator.AppendColumn(kvs.Key.callStackName);\n                csvStringGenerator.AppendColumn(kvs.Value.allocNum);\n                csvStringGenerator.AppendColumn(kvs.Value.allocAll);\n                csvStringGenerator.AppendColumn(kvs.Value.allocAll / kvs.Value.allocNum);\n                csvStringGenerator.AppendColumn(kvs.Value.allocMin);\n                csvStringGenerator.AppendColumn(kvs.Value.allocMax);\n                csvStringGenerator.NextRow();\n            }\n            return csvStringGenerator.ToString();\n        }\n        private void AppendHeaderToStringBuilder(CsvStringGenerator csvStringGenerator)\n        {\n            csvStringGenerator.AppendColumn(\"thread\");\n            // Total\n            csvStringGenerator.AppendColumn(\"SampleName\");\n            csvStringGenerator.AppendColumn(\"FullName\");\n            csvStringGenerator.AppendColumn(\"CallStack\");\n            csvStringGenerator.AppendColumn(\"calls\");\n            csvStringGenerator.AppendColumn(\"all(byte)\");\n            csvStringGenerator.AppendColumn(\"average(byte)\");\n            csvStringGenerator.AppendColumn(\"min(byte)\");\n            csvStringGenerator.AppendColumn(\"max(byte)\");\n            csvStringGenerator.NextRow();\n\n        }\n\n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_gc_detail.csv\";\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Editor/Analyzer/Impl/GcCallStackInfoAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 926a0e3638071e54e981f2dd25e21d82\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/GpuSampleToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\nusing System.Text;\nusing UTJ.ProfilerReader.BinaryData.Thread;\nusing UTJ.ProfilerReader.RawData.Protocol;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class GPUSampleToFile : AnalyzeToTextbaseFileBase\n    {\n        private struct GpuTimeInfo\n        {\n            public int time;\n            public int count;\n        }\n        private class FrameGpuTime\n        {\n            public int frameIdx;\n            public Dictionary<int, GpuTimeInfo> gpuTimeByCategory;\n\n            public void AddGpuSample(GPUTime gpuTime)\n            {\n                if(gpuTimeByCategory == null)\n                {\n                    gpuTimeByCategory = new Dictionary<int, GpuTimeInfo>();\n                }\n                GpuTimeInfo time;\n                if( gpuTimeByCategory.TryGetValue( gpuTime.gpuSection,out time))\n                {\n                    time.time += gpuTime.gpuTimeInMicroSec;\n                    time.count += 1;\n                    gpuTimeByCategory[gpuTime.gpuSection] = time;\n                }\n                else\n                {\n                    time = new GpuTimeInfo { time = gpuTime.gpuTimeInMicroSec, count = 1 };\n                    gpuTimeByCategory.Add(gpuTime.gpuSection, time);\n                }\n            }\n        }\n\n        private List<FrameGpuTime> frameGpuTimes = new List<FrameGpuTime>();\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            FrameGpuTime frameGpuTime = new FrameGpuTime();\n            frameGpuTime.frameIdx = frameData.frameIndex;\n\n            foreach ( var threadData in frameData.m_ThreadData){\n                AddGpuSampleByThread(threadData, frameGpuTime);\n            }\n            this.frameGpuTimes.Add(frameGpuTime);\n        }\n\n        private void AddGpuSampleByThread(ThreadData thread, FrameGpuTime frameGpuTime)\n        {\n            if( thread == null) { return; }\n            if( thread.m_GPUTimeSamples == null) { return; }\n            foreach( var gpuSample in thread.m_GPUTimeSamples)\n            {\n                frameGpuTime.AddGpuSample(gpuSample);\n            }\n        }\n\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            csvStringGenerator.AppendColumn(\"frameIdx\");\n\n            for (int i = 0; i < GPUTime.SECTION_NUM; ++i)\n            {\n                csvStringGenerator.AppendColumn(((GPUTime.GpuSection)i).ToString() + \"(ms)\");\n            }\n            csvStringGenerator.AppendColumn(\"callNum\");\n            for (int i = 0; i < GPUTime.SECTION_NUM; ++i)\n            {\n                csvStringGenerator.AppendColumn(((GPUTime.GpuSection)i).ToString() + \"(calls)\");\n            }\n\n            csvStringGenerator.NextRow();\n            foreach( var gpuFrame in frameGpuTimes)\n            {\n                if (gpuFrame.gpuTimeByCategory == null) { continue; }\n                csvStringGenerator.AppendColumn(gpuFrame.frameIdx);\n\n                for( int i = 0; i < GPUTime.SECTION_NUM; ++i)\n                {\n                    GpuTimeInfo val ;\n                    if(gpuFrame.gpuTimeByCategory.TryGetValue(i,out val))\n                    {\n                        csvStringGenerator.AppendColumn( (float)val.time / 1000.0f);\n                    }\n                    else\n                    {\n                        csvStringGenerator.AppendColumn(0);\n                    }\n                }\n                csvStringGenerator.AppendColumn(\"\");\n\n                for (int i = 0; i < GPUTime.SECTION_NUM; ++i)\n                {\n                    GpuTimeInfo val;\n                    if (gpuFrame.gpuTimeByCategory.TryGetValue(i, out val))\n                    {\n                        csvStringGenerator.AppendColumn(val.count);\n                    }\n                    else\n                    {\n                        csvStringGenerator.AppendColumn(0);\n                    }\n                }\n\n                csvStringGenerator.NextRow();\n            }\n            return csvStringGenerator.ToString();\n        }\n        \n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_gpu_sample.csv\";\n            }\n        }\n\n\n    }\n\n}"
  },
  {
    "path": "Editor/Analyzer/Impl/GpuSampleToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 13b9f169806de6541af34024f978dd04\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/JitInfoAnalyzeToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\n\nusing UTJ.ProfilerReader.BinaryData.Stats;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n    public class JitInfoAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n        private Dictionary<ulong, JitInfo> jitInfoDict = new Dictionary<ulong, JitInfo>();\n\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            if( frameData == null )\n            {\n                return;\n            }\n            var jitInfos = frameData.m_jitInfos;\n            if( jitInfos == null)\n            {\n                return;\n            }\n            foreach( var jitInfo in jitInfos)\n            {\n                if(jitInfo == null) { continue; }\n                if(!jitInfoDict.ContainsKey(jitInfo.codeAddr))\n                {\n                    jitInfoDict.Add(jitInfo.codeAddr, jitInfo);\n                }\n            }\n\n        }\n\n\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            AppendHeaderToStringBuilder(csvStringGenerator);\n            List<JitInfo> sortedJitInfo = new List<JitInfo>(this.jitInfoDict.Values);\n            sortedJitInfo.Sort(new JitInfo.CompareByAddr() );\n\n            foreach( var jitInfo in sortedJitInfo)\n            {\n                string name = jitInfo.name;\n                string sourceFileName = jitInfo.sourceFileName;\n                csvStringGenerator.AppendColumnAsAddr(jitInfo.codeAddr);\n                csvStringGenerator.AppendColumn(jitInfo.size);\n                csvStringGenerator.AppendColumn(name);\n                csvStringGenerator.AppendColumn(sourceFileName);\n                csvStringGenerator.AppendColumn(jitInfo.sourceFileLine);\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n\n\n        private void AppendHeaderToStringBuilder(CsvStringGenerator csvStringGenerator)\n        {\n            csvStringGenerator.AppendColumn(\"Address\");\n            // Total\n            csvStringGenerator.AppendColumn(\"Code Size\");\n            csvStringGenerator.AppendColumn(\"FunctionName\");\n            csvStringGenerator.AppendColumn(\"SourceFile\");\n            csvStringGenerator.AppendColumn(\"SourceLine\");\n            csvStringGenerator.NextRow();\n        }\n\n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_jitInfos.csv\";\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Editor/Analyzer/Impl/JitInfoAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e62bb9e4f2af06a4cb9bea7b4bbb7bd2\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/MainThreadAnalyzeToFile.cs",
    "content": "﻿using System.Collections.Generic;\n\nusing UTJ.ProfilerReader.BinaryData;\n\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class MainThreadAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n        private class SampleData\n        {\n            public string fullName;\n            public string sampleName;\n\n            public float totalSelfMsec = 0.0f;\n            public float selfMinMSec = float.MaxValue;\n            public float selfMaxMsec = 0.0f;\n\n            public float totalExecMsec = 0.0f;\n            public float execMinMSec = float.MaxValue;\n            public float execMaxMsec = 0.0f;\n\n            public int callNum = 0;\n\n            public string categoryName;\n\n            public SampleData(string fname, string name,string category)\n            {\n                this.sampleName = name;\n                this.fullName = fname;\n                this.categoryName = category;\n            }\n\n            public void Called(float selfMsec, float execMsec)\n            {\n\n                selfMinMSec = ProfilerLogUtil.Min(selfMinMSec, selfMsec);\n                selfMaxMsec = ProfilerLogUtil.Max(selfMaxMsec, selfMsec);\n                totalSelfMsec += selfMsec;\n\n                execMinMSec = ProfilerLogUtil.Min(execMinMSec, execMsec);\n                execMaxMsec = ProfilerLogUtil.Max(execMaxMsec, execMsec);\n                totalExecMsec += execMsec;\n                ++callNum;\n            }\n        }\n        private Dictionary<string, SampleData> samples = new Dictionary<string, SampleData>();\n        private int frameNum = 0;\n\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            // 特別枠で frameDataのＣＰＵ時間を追加\n            // 同一フレーム内に同じスレッド名が複数できるので…\n            Dictionary<string, int> threadNameCounter = new Dictionary<string, int>(8);\n            foreach (var thread in frameData.m_ThreadData)\n            {\n                if (thread.IsMainThread)\n                {\n                    CollectThread(frameData,thread);\n                }\n            }\n            ++frameNum;\n        }\n\n        private void CollectThread(ProfilerFrameData frameData,ThreadData thread)\n        {\n            if (thread == null || thread.m_AllSamples == null) { return; }\n            foreach (var sample in thread.m_AllSamples)\n            {\n                if (sample.parent == null)\n                {\n                    CollectFromNamedChildren(frameData,sample);\n                }\n            }\n        }\n\n        private void CollectFromNamedChildren(ProfilerFrameData frameData,ProfilerSample sample)\n        {\n            if (!string.IsNullOrEmpty(sample.sampleName))\n            {\n                string category = ProtocolData.GetCategory(frameData,unityVersion, sample.group);\n                AddSampleData(sample.fullSampleName, sample.sampleName, category, sample.selfTimeUs / 1000.0f, sample.timeUS / 1000.0f);\n            }\n            if (sample.children != null)\n            {\n                foreach (var child in sample.children)\n                {\n                    CollectFromNamedChildren(frameData,child);\n                }\n            }\n            return;\n        }\n\n        private void AddSampleData(string fullName, string sampleName,string categoryName, float selfMsec, float execMsec)\n        {\n\n            SampleData sampleData = null;\n            if (selfMsec < 0.0f)\n            {\n                ProfilerLogUtil.logErrorString(\"minus Param \" + sampleName + \":\" + selfMsec + \":\" + execMsec);\n                return;\n            }\n            if (selfMsec > 1000.0f * 50.0f)\n            {\n                ProfilerLogUtil.logErrorString(\"minus Param \" + sampleName + \":\" + selfMsec + \":\" + execMsec);\n                return;\n            }\n\n            if (!this.samples.TryGetValue(fullName, out sampleData))\n            {\n                sampleData = new SampleData(fullName, sampleName,categoryName);\n                this.samples.Add(fullName, sampleData);\n            }\n            sampleData.Called(selfMsec, execMsec);\n        }\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            csvStringGenerator.AppendColumn(\"name\").AppendColumn(\"fullname\").AppendColumn(\"category\").AppendColumn(\"callNum\").\n                AppendColumn(\"self\").AppendColumn(\"sum(msec)\").AppendColumn(\"perFrame(msec)\").AppendColumn(\"min(msec)\").AppendColumn(\"max(msec)\").\n                AppendColumn(\"total\").AppendColumn(\"sum(msec)\").AppendColumn(\"perFrame(msec)\").AppendColumn(\"min(msec)\").AppendColumn(\"max(msec)\").\n                NextRow();\n            var sampleDataList = new List<SampleData>(samples.Values);\n            sampleDataList.Sort((a, b) =>\n            {\n                if (a.totalSelfMsec > b.totalSelfMsec)\n                {\n                    return -1;\n                }else if (a.totalSelfMsec < b.totalSelfMsec)\n                {\n                    return 1;\n                }\n                return 0;\n            });\n            foreach (var sampleData in sampleDataList)\n            {\n                csvStringGenerator.AppendColumn(sampleData.sampleName).\n                    AppendColumn(sampleData.fullName).\n                    AppendColumn(sampleData.categoryName).\n                    AppendColumn(sampleData.callNum).AppendColumn(\"\");\n\n                csvStringGenerator.AppendColumn(sampleData.totalSelfMsec).\n                    AppendColumn(sampleData.totalSelfMsec / frameNum).\n                    AppendColumn(sampleData.selfMinMSec).\n                    AppendColumn(sampleData.selfMaxMsec).AppendColumn(\"\");\n\n\n                csvStringGenerator.AppendColumn(sampleData.totalExecMsec).\n                    AppendColumn(sampleData.totalExecMsec / frameNum).\n                    AppendColumn(sampleData.execMinMSec).\n                    AppendColumn(sampleData.execMaxMsec);\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_main_self.csv\";\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "Editor/Analyzer/Impl/MainThreadAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 180ee3acbe5f93944998f208ebc9db00\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/MainThreadCategoryAnalyzeToFile.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\n\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class MainThreadCategoryAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n        private class FrameByCategory\n        {\n            public Dictionary<string, float> frameData;\n            public int frameIdx;\n\n            public void AddData(string category,float msec)\n            {\n                if(frameData == null)\n                {\n                    frameData = new Dictionary<string, float>();\n                }\n                float val;\n                if( frameData.TryGetValue(category,out val) ){\n                    frameData[category] = val + msec;\n                }\n                else\n                {\n                    frameData.Add( category , msec );\n                }\n            }\n\n            public void AppendCsv(CsvStringGenerator csvStringGenerator, List<string> categoriesStr)\n            {\n                foreach (var category in categoriesStr)\n                {\n                    float val;\n\n                    if (!frameData.TryGetValue(category, out val))\n                    {\n                        val = 0.0f;\n                    }\n                    csvStringGenerator.AppendColumn(val);\n                }\n            }\n        }\n\n        private Dictionary<int,string> categoryDictionary;\n        private List<string> categoriesStr;\n        private List<FrameByCategory> frames = new List<FrameByCategory>();\n\n        private void CollectThread(ThreadData thread,FrameByCategory frameByCategory)\n        {\n            if (thread.m_AllSamples == null) { return; }\n            foreach (var sample in thread.m_AllSamples)\n            {\n                string category = null;\n                if(categoryDictionary.TryGetValue(sample.group,out category) ){\n                    frameByCategory.AddData(categoriesStr[sample.group], sample.selfTimeUs * 0.001f);\n                }\n            }\n        }\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            // Categoryのセットアップ\n            SetupCategories(frameData);\n            FrameByCategory frameByCategory = new FrameByCategory();\n            frameByCategory.frameIdx = frameData.frameIndex;\n            // 特別枠で frameDataのＣＰＵ時間を追加\n            // 同一フレーム内に同じスレッド名が複数できるので…\n            Dictionary<string, int> threadNameCounter = new Dictionary<string, int>(8);\n            foreach (var thread in frameData.m_ThreadData)\n            {\n                if (thread.IsMainThread)\n                {\n                    CollectThread(thread, frameByCategory);\n                }\n            }\n            this.frames.Add(frameByCategory);\n        }\n        private void SetupCategories(ProfilerFrameData frameData)\n        {\n            if(this.categoryDictionary != null)\n            {\n                return;\n            }\n            this.categoriesStr = new List<string>();\n            this.categoryDictionary = new Dictionary<int,string>();\n            var categories = ProtocolData.GetCategories(frameData, this.unityVersion);\n            foreach( var item in categories)\n            {\n                string name = item.Value.name;\n                int idx = (int)item.Value.categoryId;\n                if (!categoryDictionary.ContainsKey(idx))\n                {\n                    categoriesStr.Add(name);\n                    categoryDictionary.Add(idx,name);\n                }\n            }\n        }\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            csvStringGenerator.AppendColumn(\"frameIdx\");\n            foreach( var str in categoriesStr)\n            {\n                csvStringGenerator.AppendColumn(str+\"(msec)\");\n            }            \n            csvStringGenerator.NextRow();\n\n            foreach( var frame in frames)\n            {\n                csvStringGenerator.AppendColumn(frame.frameIdx);\n                frame.AppendCsv(csvStringGenerator,this.categoriesStr);\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n        \n        protected override string FooterName\n        {\n            get\n            {\n                return \"_category_mainThread_frame.csv\";\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "Editor/Analyzer/Impl/MainThreadCategoryAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: b29edfc38841eb247a4efcfbb71c9123\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/MemoryAnalyzeToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\n\nusing UTJ.ProfilerReader.BinaryData.Stats;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n    public class MemoryAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n        private List<int> frameIdxList = new List<int>();\n        private List<MemoryStats> memoryStatsList = new List<MemoryStats>();\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            if( frameData == null || frameData.allStats == null || frameData.allStats.memoryStats == null)\n            {\n                return;\n            }\n            frameIdxList.Add(frameData.frameIndex);\n            memoryStatsList.Add( frameData.allStats.memoryStats );\n        }\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n\n            AppendHeaderToStringBuilder(csvStringGenerator);\n\n            for ( int i = 0; i < memoryStatsList.Count; ++i)\n            {\n                MemoryStats memoryStats = memoryStatsList[i];\n                csvStringGenerator.AppendColumn(frameIdxList[i]);\n                csvStringGenerator.AppendColumn(\"\");\n                // Used Memory\n                csvStringGenerator.AppendColumn(memoryStats.bytesUsedTotal);\n                csvStringGenerator.AppendColumn(memoryStats.bytesUsedUnity);\n                csvStringGenerator.AppendColumn(memoryStats.bytesUsedMono);\n                csvStringGenerator.AppendColumn(memoryStats.bytesUsedGFX);\n                csvStringGenerator.AppendColumn(memoryStats.bytesUsedFMOD);\n                csvStringGenerator.AppendColumn(memoryStats.bytesUsedVideo);\n                csvStringGenerator.AppendColumn(memoryStats.bytesUsedProfiler);\n                csvStringGenerator.AppendColumn(\"\");\n\n                // Reserved Memory\n                csvStringGenerator.AppendColumn(memoryStats.bytesReservedTotal);\n                csvStringGenerator.AppendColumn(memoryStats.bytesReservedUnity);\n                csvStringGenerator.AppendColumn(memoryStats.bytesReservedMono);\n                csvStringGenerator.AppendColumn(memoryStats.bytesReservedFMOD);\n                csvStringGenerator.AppendColumn(memoryStats.bytesReservedVideo);\n                csvStringGenerator.AppendColumn(memoryStats.bytesReservedProfiler);\n                csvStringGenerator.AppendColumn(\"\");\n\n                // by Assets\n                csvStringGenerator.AppendColumn(memoryStats.textureCount);\n                csvStringGenerator.AppendColumn(memoryStats.textureBytes);\n                csvStringGenerator.AppendColumn(memoryStats.meshCount);\n                csvStringGenerator.AppendColumn(memoryStats.meshBytes);\n                csvStringGenerator.AppendColumn(memoryStats.materialCount);\n                csvStringGenerator.AppendColumn(memoryStats.materialBytes);\n                csvStringGenerator.AppendColumn(memoryStats.audioCount);\n                csvStringGenerator.AppendColumn(memoryStats.audioBytes);\n                csvStringGenerator.AppendColumn(memoryStats.assetCount);\n                csvStringGenerator.AppendColumn(memoryStats.gameObjectCount);\n                csvStringGenerator.AppendColumn(memoryStats.sceneObjectCount);\n                csvStringGenerator.AppendColumn(memoryStats.totalObjectsCount);\n                csvStringGenerator.AppendColumn(\"\");\n\n                // GC\n                csvStringGenerator.AppendColumn(memoryStats.frameGCAllocCount);\n                csvStringGenerator.AppendColumn(memoryStats.frameGCAllocBytes);\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n        private void AppendHeaderToStringBuilder(CsvStringGenerator csvStringGenerator)\n        {\n            csvStringGenerator.AppendColumn(\"frameIdx\");\n            csvStringGenerator.AppendColumn(\"UsedMemory\");\n            // Used Memory\n            csvStringGenerator.AppendColumn(\"bytesUsedTotal\");\n            csvStringGenerator.AppendColumn(\"bytesUsedUnity\");\n            csvStringGenerator.AppendColumn(\"bytesUsedMono\");\n            csvStringGenerator.AppendColumn(\"bytesUsedGFX\");\n            csvStringGenerator.AppendColumn(\"bytesUsedFMOD\");\n            csvStringGenerator.AppendColumn(\"bytesUsedVideo\");\n            csvStringGenerator.AppendColumn(\"bytesUsedProfiler\");\n\n            csvStringGenerator.AppendColumn(\"ReservedMemory\");\n            // Reserved Memory\n            csvStringGenerator.AppendColumn(\"bytesReservedTotal\");\n            csvStringGenerator.AppendColumn(\"bytesReservedUnity\");\n            csvStringGenerator.AppendColumn(\"bytesReservedMono\");\n            csvStringGenerator.AppendColumn(\"bytesReservedFMOD\");\n            csvStringGenerator.AppendColumn(\"bytesReservedVideo\");\n            csvStringGenerator.AppendColumn(\"bytesReservedProfiler\");\n\n            csvStringGenerator.AppendColumn(\"AssetUsage\");\n            // by Assets\n            csvStringGenerator.AppendColumn(\"textureCount\");\n            csvStringGenerator.AppendColumn(\"textureBytes\");\n            csvStringGenerator.AppendColumn(\"meshCount\");\n            csvStringGenerator.AppendColumn(\"meshBytes\");\n            csvStringGenerator.AppendColumn(\"meshCount\");\n            csvStringGenerator.AppendColumn(\"meshBytes\");\n            csvStringGenerator.AppendColumn(\"materialCount\");\n            csvStringGenerator.AppendColumn(\"materialBytes\");\n            csvStringGenerator.AppendColumn(\"audioCount\");\n            csvStringGenerator.AppendColumn(\"audioBytes\");\n            csvStringGenerator.AppendColumn(\"assetCount\");\n            csvStringGenerator.AppendColumn(\"gameObjectCount\");\n            csvStringGenerator.AppendColumn(\"sceneObjectCount\");\n            csvStringGenerator.AppendColumn(\"totalObjectsCount\");\n            csvStringGenerator.AppendColumn(\"GC\");\n\n            // GC\n            csvStringGenerator.AppendColumn(\"frameGCAllocCount\");\n            csvStringGenerator.AppendColumn(\"frameGCAllocBytes\");\n            csvStringGenerator.NextRow();\n\n        }\n        \n        protected override string FooterName\n        {\n            get\n            {\n                return \"_memory.csv\";\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Editor/Analyzer/Impl/MemoryAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 615d3f2b68411c54d9571d4b44071800\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/RenderThreadToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\nusing System.Text;\n\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class RenderThreadToFile : AnalyzeToTextbaseFileBase\n    {\n\n        private struct CameraRenderData\n        {\n            public float renderTime;\n            public float updateDepth;\n            public float opaque;\n            public float transparent;\n            public float imageEffect;\n\n\n            public void AppendToStringBuilder(CsvStringGenerator csvStringGenerator)\n            {\n                csvStringGenerator.AppendColumn(renderTime);\n                csvStringGenerator.AppendColumn(updateDepth);\n                csvStringGenerator.AppendColumn(opaque);\n                csvStringGenerator.AppendColumn(transparent);\n                csvStringGenerator.AppendColumn(imageEffect);\n            }\n        }\n\n\n        private class FrameRenderingData\n        {\n            public int frameIdx;\n            public float processCommandsTime;\n            public float waitForCommandsTime;\n\n            public float scheduleGeometryJobTime;\n            public int scheduleGeometryJobNum;\n            public float presentFrameTime;\n            public float guiRepaint;\n\n            public List<CameraRenderData> cameraRenders = new List<CameraRenderData>(8);\n\n            public void AppendToCsvGenerator(CsvStringGenerator csvStringGenerator)\n            {\n                csvStringGenerator.AppendColumn(frameIdx);\n                csvStringGenerator.AppendColumn(processCommandsTime);\n                csvStringGenerator.AppendColumn(waitForCommandsTime);\n                csvStringGenerator.AppendColumn(scheduleGeometryJobTime);\n                csvStringGenerator.AppendColumn(scheduleGeometryJobNum);\n                csvStringGenerator.AppendColumn(presentFrameTime);\n                csvStringGenerator.AppendColumn(guiRepaint);\n                csvStringGenerator.AppendColumn( cameraRenders.Count);\n\n                foreach (var cameraRender in cameraRenders)\n                {\n                    csvStringGenerator.AppendColumn(\"\");\n                    cameraRender.AppendToStringBuilder(csvStringGenerator);\n                }\n            }\n        }\n\n        private List<FrameRenderingData> frameRenderingDatas = new List<FrameRenderingData>(512);\n        private int maxCameraNum = 0;\n\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            foreach( var threadData in frameData.m_ThreadData){\n                if(threadData.m_ThreadName == \"Render Thread\")\n                {\n                    CollectRenderThreadData(frameData.frameIndex, threadData);\n                }\n            }\n        }\n\n        private void CollectRenderThreadData(int frameIdx,ThreadData threadData)\n        {\n            if(threadData.m_AllSamples == null) { return; }\n            FrameRenderingData frameRenderingData = new FrameRenderingData();\n            frameRenderingData.frameIdx = frameIdx;\n            frameRenderingData.processCommandsTime = threadData.m_AllSamples[0].timeUS / 1000.0f;\n\n            int cameraNum = 0;\n            foreach ( var sample in threadData.m_AllSamples)\n            {\n                switch(sample.sampleName ){\n                    case \"Camera.Render\":\n                        {\n                            var cameraRender = CollectCameraRenderData(sample);\n                            frameRenderingData.cameraRenders.Add(cameraRender);\n                            ++cameraNum;\n                        }\n                        break;\n                    case \"Gfx.WaitForCommands\":\n                        frameRenderingData.waitForCommandsTime += sample.timeUS / 1000.0f;\n                        break;\n                    case \"Gfx.PresentFrame\":\n                        frameRenderingData.presentFrameTime += sample.timeUS / 1000.0f;\n                        break;\n                    case \"ScheduleGeometryJobs\":\n                        frameRenderingData.scheduleGeometryJobTime += sample.timeUS / 1000.0f;\n                        frameRenderingData.scheduleGeometryJobNum += 1;\n                        break;\n                    case \"GUIRepaint\":\n                        frameRenderingData.guiRepaint += sample.timeUS / 1000.0f;\n                        break;\n                }\n            }\n            if(maxCameraNum < cameraNum)\n            {\n                maxCameraNum = cameraNum;\n            }\n            frameRenderingDatas.Add(frameRenderingData);\n        }\n\n        private CameraRenderData CollectCameraRenderData( ProfilerSample profilerSample)\n        {\n            CameraRenderData renderData = new CameraRenderData();\n            renderData.renderTime = profilerSample.timeUS / 1000.0f; \n            VisitChildren(profilerSample, (sample) => {\n                switch(sample.sampleName){\n                    case \"UpdateDepthTexture\":\n                        renderData.updateDepth = sample.timeUS / 1000.0f;\n                        return true;\n                    case \"Render.OpaqueGeometry\":\n                        renderData.opaque = sample.timeUS / 1000.0f;\n                        return true;\n                    case \"Render.TransparentGeometry\":\n                        renderData.transparent = sample.timeUS / 1000.0f;\n                        return true;\n                    case \"Camera.ImageEffects\":\n                        renderData.imageEffect = sample.timeUS / 1000.0f;\n                        return true;\n                }\n                return false;\n            });\n            return renderData;\n        }\n\n        private List<ProfilerSample> FindChildren(ProfilerSample profilerSample,string name)\n        {\n            List<ProfilerSample> results = new List<ProfilerSample>();\n\n            return results;\n        }\n        private void VisitChildren(ProfilerSample sample, \n            System.Func<ProfilerSample,bool> filter)\n        {\n            if( sample == null) { return; }\n            if( filter(sample)) {\n                return;\n            }\n            if( sample.children == null)\n            {\n                return;\n            }\n            foreach( var child in sample.children)\n            {\n                VisitChildren(child, filter);\n            }\n        }\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            csvStringGenerator.AppendColumn(\"frameIdx\").AppendColumn(\"processCommandsTime\").\n                AppendColumn(\"waitForCommandsTime\").AppendColumn(\"scheduleGeometryJobTime\").AppendColumn(\"scheduleGeometryJobNum\").AppendColumn(\"presentFrameTime\").AppendColumn(\"guiRepaint\").AppendColumn(\"cameraRenders\");\n\n            for (int i = 0; i < maxCameraNum; ++i)\n            {\n                csvStringGenerator.AppendColumn(\"Camera\"+i);\n                csvStringGenerator.AppendColumn(\"renderTime\").AppendColumn(\"updateDepth\").AppendColumn(\"opaque\").AppendColumn(\"transparent\").AppendColumn(\"imageEffect\");\n            }\n            csvStringGenerator.NextRow();\n\n            foreach (var frameRenderingData in this.frameRenderingDatas)\n            {\n                frameRenderingData.AppendToCsvGenerator(csvStringGenerator);\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n        \n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_renderthread.csv\";\n            }\n        }\n\n\n    }\n\n}"
  },
  {
    "path": "Editor/Analyzer/Impl/RenderThreadToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ea57c279a8d206a4484872add86970c8\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/RenderingAnalyzeToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\n\nusing UTJ.ProfilerReader.BinaryData.Stats;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n    public class RenderingAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n\n        const string FrameWholeDataSpecialKey = \"CPUTotal\";\n\n        private List<int> frameIdxList = new List<int>();\n        private List<DrawStats> drawStatsList = new List<DrawStats>();\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            if( frameData == null || frameData.allStats == null || frameData.allStats.drawStats == null)\n            {\n                return;\n            }\n            frameIdxList.Add(frameData.frameIndex);\n            drawStatsList.Add(frameData.allStats.drawStats);\n        }\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            AppendHeaderToStringBuilder(csvStringGenerator);\n\n            for (int i = 0; i < drawStatsList.Count; ++i)\n            {\n                DrawStats drawStats = drawStatsList[i];\n                csvStringGenerator.AppendColumn(frameIdxList[i]);\n\n                csvStringGenerator.AppendColumn(\"\");\n                // Total\n                csvStringGenerator.AppendColumn(drawStats.setPassCalls);\n                csvStringGenerator.AppendColumn(drawStats.drawCalls);\n                csvStringGenerator.AppendColumn(drawStats.batches);\n                csvStringGenerator.AppendColumn(drawStats.triangles);\n                csvStringGenerator.AppendColumn(drawStats.vertices);\n                csvStringGenerator.AppendColumn(\"\");\n                // DynamicBatching\n                csvStringGenerator.AppendColumn(drawStats.dynamicBatchedDrawCalls);\n                csvStringGenerator.AppendColumn(drawStats.dynamicBatchedTriangles);\n                csvStringGenerator.AppendColumn(drawStats.dynamicBatchedTriangles);\n                csvStringGenerator.AppendColumn(drawStats.dynamicBatchedVertices);\n                csvStringGenerator.AppendColumn(\"\");\n                // static batching\n                csvStringGenerator.AppendColumn(drawStats.staticBatchedDrawCalls);\n                csvStringGenerator.AppendColumn(drawStats.staticBatchedTriangles);\n                csvStringGenerator.AppendColumn(drawStats.staticBatchedTriangles);\n                csvStringGenerator.AppendColumn(drawStats.staticBatchedVertices);\n                // instancing    \n                csvStringGenerator.AppendColumn(\"\");\n                csvStringGenerator.AppendColumn(drawStats.hasInstancing);\n                csvStringGenerator.AppendColumn(drawStats.instancedBatchedDrawCalls);\n                csvStringGenerator.AppendColumn(drawStats.instancedBatches);\n                csvStringGenerator.AppendColumn(drawStats.instancedTriangles);\n                csvStringGenerator.AppendColumn(drawStats.instancedVertices);\n                //screen Info\n                csvStringGenerator.AppendColumn(\"\");\n                csvStringGenerator.AppendColumn(drawStats.screenWidth);\n                csvStringGenerator.AppendColumn(drawStats.screenHeight);\n                csvStringGenerator.AppendColumn(drawStats.screenBytes);\n                // RenderTexture Info\n                csvStringGenerator.AppendColumn(\"\");\n                csvStringGenerator.AppendColumn(drawStats.renderTextureCount);\n                csvStringGenerator.AppendColumn(drawStats.renderTextureBytes);\n                csvStringGenerator.AppendColumn(drawStats.renderTextureStateChanges);\n                // SkinnedMesh\n                csvStringGenerator.AppendColumn(\"\");\n                csvStringGenerator.AppendColumn(drawStats.visibleSkinnedMeshes);\n                // etc...\n                csvStringGenerator.AppendColumn(\"\");\n                csvStringGenerator.AppendColumn(drawStats.totalAvailableVRamMBytes);\n                csvStringGenerator.AppendColumn(drawStats.vboTotal);\n                csvStringGenerator.AppendColumn(drawStats.vboUploads);\n                csvStringGenerator.AppendColumn(drawStats.ibUploads);\n                csvStringGenerator.AppendColumn(drawStats.shadowCasters);\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n        private void AppendHeaderToStringBuilder(CsvStringGenerator csvStringGenerator)\n        {\n            csvStringGenerator.AppendColumn(\"frameIdx\");\n            // Total\n            csvStringGenerator.AppendColumn(\"Total\");\n            csvStringGenerator.AppendColumn(\"setPassCalls\");\n            csvStringGenerator.AppendColumn(\"drawCalls\");\n            csvStringGenerator.AppendColumn(\"batches\");\n            csvStringGenerator.AppendColumn(\"triangles\");\n            csvStringGenerator.AppendColumn(\"vertices\");\n            // DynamicBatching\n            csvStringGenerator.AppendColumn(\"DynamicBatching\");\n            csvStringGenerator.AppendColumn(\"dynamicBatchedDrawCalls\");\n            csvStringGenerator.AppendColumn(\"dynamicBatchedTriangles\");\n            csvStringGenerator.AppendColumn(\"dynamicBatchedTriangles\");\n            csvStringGenerator.AppendColumn(\"dynamicBatchedVertices\");\n            // static batching\n            csvStringGenerator.AppendColumn(\"StaticBatching\");\n            csvStringGenerator.AppendColumn(\"staticBatchedDrawCalls\");\n            csvStringGenerator.AppendColumn(\"staticBatchedTriangles\");\n            csvStringGenerator.AppendColumn(\"staticBatchedTriangles\");\n            csvStringGenerator.AppendColumn(\"staticBatchedVertices\");\n            // instancing    \n            csvStringGenerator.AppendColumn(\"Instancing\");\n            csvStringGenerator.AppendColumn(\"hasInstancing\");\n            csvStringGenerator.AppendColumn(\"instancedBatchedDrawCalls\");\n            csvStringGenerator.AppendColumn(\"instancedBatches\");\n            csvStringGenerator.AppendColumn(\"instancedTriangles\");\n            csvStringGenerator.AppendColumn(\"instancedVertices\");\n            //screen Info\n            csvStringGenerator.AppendColumn(\"ScreenInfo\");\n            csvStringGenerator.AppendColumn(\"screenWidth\");\n            csvStringGenerator.AppendColumn(\"screenHeight\");\n            csvStringGenerator.AppendColumn(\"screenBytes\");\n            // RenderTexture Info\n            csvStringGenerator.AppendColumn(\"RenderTextureInfo\");\n            csvStringGenerator.AppendColumn(\"renderTextureCount\");\n            csvStringGenerator.AppendColumn(\"renderTextureBytes\");\n            csvStringGenerator.AppendColumn(\"renderTextureStateChanges\");\n            // SkinnedMesh\n            csvStringGenerator.AppendColumn(\"SkinnedMesh\");\n            csvStringGenerator.AppendColumn(\"visibleSkinnedMeshes\");\n            // etc...\n            csvStringGenerator.AppendColumn(\"etc\");\n            csvStringGenerator.AppendColumn(\"totalAvailableVRamMBytes\");\n            csvStringGenerator.AppendColumn(\"vboTotal\");\n            csvStringGenerator.AppendColumn(\"vboUploads\");\n            csvStringGenerator.AppendColumn(\"ibUploads\");\n            csvStringGenerator.AppendColumn(\"shadowCasters\");\n            csvStringGenerator.NextRow();\n\n        }\n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_rendering.csv\";\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Editor/Analyzer/Impl/RenderingAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 659f15cfe80d1a9479e0a497890dc806\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/ScreenshotToPng.cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\nusing UTJ.ProfilerReader.RawData.Protocol;\nusing System.Text;\nusing System.IO;\n\n#if UNITY_EDITOR\nusing UnityEngine;\n#endif\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class ScreenShotToProfiler : IAnalyzeFileWriter\n    {\n\n        public static readonly System.Guid MetadataGuid = new System.Guid(\"4389DCEB-F9B3-4D49-940B-E98482F3A3F8\");\n        public static readonly int InfoTag = -1;\n\n        private string outputPath;\n        private string logFile;\n        private bool createDir = false;\n        private StringBuilder stringBuilder = new StringBuilder();\n\n        public enum TextureCompress : byte\n        {\n            None = 0,\n            RGB_565 = 1,\n            PNG = 2,\n            JPG_BufferRGB565 = 3,\n            JPG_BufferRGBA = 4,\n        }\n        private class CaptureData\n        {\n            public int profilerFrameIndex;\n            public int idx;\n            public int width;\n            public int height;\n            public int originWidth;\n            public int originHeight;\n            public TextureCompress compress;\n\n            public CaptureData(int frameIdx ,byte[] data)\n            {\n                this.profilerFrameIndex = frameIdx;\n                this.idx = GetIntValue(data, 0);\n                this.width = GetShortValue(data, 4);\n                this.height = GetShortValue(data, 6);\n                this.originWidth = GetShortValue(data, 8);\n                this.originHeight = GetShortValue(data, 10);\n\n                if (data.Length > 12)\n                {\n                    this.compress = (ScreenShotToProfiler.TextureCompress)data[12];\n                }\n                else\n                {\n                    this.compress = ScreenShotToProfiler.TextureCompress.None;\n                }\n\n            }\n\n            public static int GetIntValue(byte[] bin, int offset)\n            {\n                return (bin[offset + 0] << 0) +\n                    (bin[offset + 1] << 8) +\n                    (bin[offset + 2] << 16) +\n                    (bin[offset + 3] << 24);\n            }\n            public static int GetShortValue(byte[] bin, int offset)\n            {\n                return (bin[offset + 0] << 0) +\n                    (bin[offset + 1] << 8);\n            }\n        }\n        private Dictionary<int, CaptureData> captureFrameData = new Dictionary<int, CaptureData>();\n\n\n        public void CollectData(ProfilerFrameData frameData)\n        {\n            foreach( var thread in frameData.m_ThreadData)\n            {\n                if (thread.IsMainThread)\n                {\n                    ExecuteThreadData(frameData.frameIndex,thread);\n                }\n            }\n        }\n        private void ExecuteThreadData(int frameIdx,ThreadData thread)\n        {\n            if(thread == null || thread.m_AllSamples == null) { return; }\n            foreach( var sample in thread.m_AllSamples)\n            {\n                if( sample == null || sample.sampleName != RawDataDefines.EmitFramemetataSample)\n                {\n                    continue;\n                }\n                if( sample.metaDatas == null || \n                    sample.metaDatas.metadatas == null ) { \n                    continue; \n                }\n                ExecuteFrameMetadata(frameIdx,sample);\n            }\n        }\n\n        private void ExecuteFrameMetadata(int frameIdx,ProfilerSample sample)\n        {\n            var metadatas = sample.metaDatas.metadatas;\n            if (metadatas.Count < 2)\n            {\n                return;\n            }\n            var guidBin = metadatas[0].convertedObject as byte[];\n            var tagId = (int)metadatas[1].convertedObject;\n            var valueBin = metadatas[2].convertedObject as byte[];\n            if (guidBin == null || valueBin == null)\n            {\n                return;\n            }\n            System.Guid guid = new System.Guid(guidBin);\n\n            CaptureData captureData = null;\n            if (guid != MetadataGuid)\n            {\n                return;\n            }\n            if (tagId == InfoTag)\n            {\n                captureData = new CaptureData(frameIdx,valueBin);\n                this.captureFrameData.Add(captureData.idx, captureData);\n                return;\n            }\n            if( this.captureFrameData.TryGetValue(tagId,out captureData)){\n                ExecuteBinData(captureData, valueBin);\n            }\n        }\n\n        private void InitDirectory()\n        {\n            if (!createDir)\n            {\n                if (!Directory.Exists(this.outputPath))\n                {\n                    Directory.CreateDirectory(this.outputPath);\n                }\n                createDir = true;\n            }\n        }\n\n        // execute data\n        private void ExecuteBinData(CaptureData captureData,byte[] binData)\n        {\n            this.InitDirectory();\n\n            string file = GetFilePath(captureData);\n            byte[] pngBin = GetImageBin(captureData,binData);\n            if ( pngBin != null)\n            {\n                File.WriteAllBytes(file, pngBin);\n            }\n        }\n        private byte[] GetImageBin(CaptureData captureData,byte[] binData)\n        {\n            if(binData == null) { return null; }\n            switch (captureData.compress)\n            {\n#if UNITY_EDITOR\n                case TextureCompress.None:\n                    return ImageConversion.EncodeArrayToPNG(binData,\n                        UnityEngine.Experimental.Rendering.GraphicsFormat.R8G8B8A8_SRGB,\n                        (uint)captureData.width, (uint)captureData.height);\n                case TextureCompress.RGB_565:\n                    return ImageConversion.EncodeArrayToPNG(binData,\n                        UnityEngine.Experimental.Rendering.GraphicsFormat.R5G6B5_UNormPack16,\n                        (uint)captureData.width, (uint)captureData.height);\n#endif\n                case TextureCompress.PNG:\n                case TextureCompress.JPG_BufferRGB565:\n                case TextureCompress.JPG_BufferRGBA:\n                    return binData;\n            }\n            return null;\n        }\n        private string GetFilePath(CaptureData captureData)\n        {\n            stringBuilder.Length = 0;\n            stringBuilder.Append(this.outputPath).Append(\"/ss-\");\n            stringBuilder.Append(string.Format(\"{0:D5}\", captureData.idx));\n            switch (captureData.compress)\n            {\n                case TextureCompress.None:\n                case TextureCompress.RGB_565:\n                case TextureCompress.PNG:\n                    stringBuilder.Append(\".png\");\n                    break;\n                case TextureCompress.JPG_BufferRGB565:\n                case TextureCompress.JPG_BufferRGBA:\n                    stringBuilder.Append(\".jpg\");\n                    break;\n            }\n            return stringBuilder.ToString();\n        }\n\n\n        public void SetFileInfo(string logfilename, string outputpath)\n        {\n            this.outputPath = Path.Combine(outputpath, \"screenshots\");\n            this.logFile = logfilename;\n        }\n\n        public void WriteResultFile(string logfilaneme, string outputpath)\n        {\n        }\n\n        // nothing todo...\n        public void SetInfo(ProfilerLogFormat logformat, string unityVersion, uint dataversion, ushort platform)\n        {\n        }\n\n    }\n\n}"
  },
  {
    "path": "Editor/Analyzer/Impl/ScreenshotToPng.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 79348514f73120440b42f98f02a29bbf\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/ShaderCompileToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\nusing System.Text;\nusing UTJ.ProfilerReader.BinaryData.Thread;\nusing UTJ.ProfilerReader.RawData.Protocol;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class ShaderCompileToFile : AnalyzeToTextbaseFileBase\n    {\n        private class ShaderCompileInfo\n        {\n            public int frameIdx = 0;\n            public string shader;\n            public float msec = 0.0f;\n            public string pass;\n            public string stage;\n            public string keywords;\n            public bool callFromWarmup = false;\n\n            public ShaderCompileInfo()\n            {\n                this.shader = \"\";\n                this.pass = \"\";\n                this.stage = \"\";\n                this.keywords = \"\";\n            }\n        }\n\n        private List<ShaderCompileInfo> compileInfos = new List<ShaderCompileInfo>();\n        private bool hasPassStageKeywordsInfo = false;\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n\n            foreach ( var threadData in frameData.m_ThreadData){\n                CollectThreadData(frameData.frameIndex,threadData);\n            }\n        }\n\n        private void CollectThreadData(int frameIdx,ThreadData thread)\n        {\n            if( thread == null) { return; }\n            if( thread.m_AllSamples == null) { return; }\n\n            foreach( var sample in thread.m_AllSamples)\n            {\n                if (sample.sampleName == \"Shader.CreateGPUProgram\")\n                {\n                    AddShaderCompileSample(frameIdx, sample);\n                }\n            }\n        }\n\n\n        private void AddShaderCompileSample(int frameIdx,ProfilerSample sampleData)\n        {\n            var compileInfo = new ShaderCompileInfo();\n            compileInfo.frameIdx = frameIdx;\n            compileInfo.msec = sampleData.timeUS / 1000.0f;\n            compileInfo.callFromWarmup = IsCalledWarmup(sampleData.parent);\n            if( sampleData.metaDatas != null )\n            {\n                var metadatas = sampleData.metaDatas.metadatas;\n                if( metadatas != null)\n                {\n                    if (metadatas.Count > 0)\n                    {\n                        compileInfo.shader = metadatas[0].convertedObject as string;\n                    }\n                    if (metadatas.Count > 1)\n                    {\n                        compileInfo.pass = metadatas[1].convertedObject as string;\n                        this.hasPassStageKeywordsInfo = true;\n                    }\n\n                    if (metadatas.Count > 2)\n                    {\n                        compileInfo.stage = metadatas[2].convertedObject as string;\n                    }\n\n                    if (metadatas.Count > 3)\n                    {\n                        compileInfo.keywords = metadatas[3].convertedObject as string;\n                    }\n                }\n            }\n            this.compileInfos.Add(compileInfo);\n        }\n        //\n        private bool IsCalledWarmup(ProfilerSample sampleData)\n        {\n            for (var current = sampleData; current != null; current = current.parent)\n            {\n                if( current.sampleName == \"ShaderVariantCollection.WarmupShaders\" ||\n                    current.sampleName == \"Shader.WarmupAllShaders\")\n                {\n                    return true;\n                }\n            }\n            //            \"ShaderVariantCollection.WarmupShaders\"\n            return false;\n        }\n\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            csvStringGenerator.AppendColumn(\"frameIdx\");\n            csvStringGenerator.AppendColumn(\"Shader\")\n                .AppendColumn(\"exec(ms)\").AppendColumn(\"isWarmupCall\");\n            if (this.hasPassStageKeywordsInfo)\n            {\n                csvStringGenerator.AppendColumn(\"pass\")\n                    .AppendColumn(\"stage\")\n                    .AppendColumn(\"keyword\");\n            }\n            csvStringGenerator.NextRow();\n            foreach (var compileInfo in this.compileInfos)\n            {\n                if( compileInfo == null) { continue; }\n                    \n                csvStringGenerator.AppendColumn(compileInfo.frameIdx)\n                    .AppendColumn(compileInfo.shader)\n                    .AppendColumn(compileInfo.msec)\n                    .AppendColumn(compileInfo.callFromWarmup);\n                if (this.hasPassStageKeywordsInfo) {\n                    csvStringGenerator.AppendColumn(compileInfo.pass).\n                            AppendColumn(compileInfo.stage).\n                            AppendColumn(compileInfo.keywords);\n                }\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n        \n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_shader_compile.csv\";\n            }\n        }\n\n\n    }\n\n}"
  },
  {
    "path": "Editor/Analyzer/Impl/ShaderCompileToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 35071278dc1dc3c4eb59250e45d74b73\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/ThreadAnalyzeToFile.cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\n\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n\n    public class ThreadAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n        private class ThreadViewData\n        {\n            public int maxFrame = 0;\n            public string threadName;\n            public Dictionary<int, float> totalMsecList;\n            public Dictionary<int, float> idleMsecList;\n\n            public Dictionary<int, int> totalCount;\n            public Dictionary<int, int> idleCount;\n\n            public ThreadViewData(string name)\n            {\n                this.threadName = name;\n                this.totalMsecList = new Dictionary<int, float>(512);\n                this.idleMsecList = new Dictionary<int, float>(512);\n                idleCount = new Dictionary<int, int>(512);\n                totalCount = new Dictionary<int, int>(512);\n            }\n\n            public void AddMsec(int frame, float total, float idle, int totalCnt, int idleCnt)\n            {\n                maxFrame = ProfilerLogUtil.Max(frame, maxFrame);\n                if (!this.totalMsecList.ContainsKey(frame))\n                {\n\n                    this.totalMsecList.Add(frame, total);\n                    this.idleMsecList.Add(frame, idle);\n                    this.totalCount.Add(frame, totalCnt);\n                    this.idleCount.Add(frame, idleCnt);\n                }\n                else\n                {\n                    ProfilerLogUtil.logErrorString(\"same frame \" + threadName +\"::\" + frame);\n                }\n            }\n\n            public void GetMSecData(int frame, out float total, out float idle, out int totalCnt, out int idleCnt)\n            {\n                total = 0.0f;\n                idle = 0.0f;\n                totalMsecList.TryGetValue(frame, out total);\n                idleMsecList.TryGetValue(frame, out idle);\n                totalCount.TryGetValue(frame, out totalCnt);\n                idleCount.TryGetValue(frame, out idleCnt);\n            }\n        }\n        private Dictionary<string, ThreadViewData> viewData = new Dictionary<string, ThreadViewData>();\n\n        const string FrameWholeDataSpecialKey = \"CPUTotal\";\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            // 特別枠で frameDataのＣＰＵ時間を追加\n            ThreadViewData frameViewData = null;\n            if (!this.viewData.TryGetValue(FrameWholeDataSpecialKey, out frameViewData))\n            {\n                frameViewData = new ThreadViewData(FrameWholeDataSpecialKey);\n                viewData.Add(FrameWholeDataSpecialKey, frameViewData);\n            }\n            frameViewData.AddMsec(frameData.frameIndex, frameData.m_TotalCPUTimeInMicroSec / 1000.0f, 0.0f, 0, 0);\n\n            // 同一フレーム内に同じスレッド名が複数できるので…\n            Dictionary<string, int> threadNameCounter = new Dictionary<string, int>(8);\n            foreach (var thread in frameData.m_ThreadData)\n            {\n                string threadName = thread.FullName;\n                if (threadName == null) { continue; }\n                int cnt = 0;\n                if (threadNameCounter.TryGetValue(threadName, out cnt))\n                {\n                    ++cnt;\n                    threadName = threadName + cnt;\n                }\n                threadNameCounter[threadName] = cnt;\n                this.AddDataTo(frameData.frameIndex, threadName, thread);\n            }\n        }\n\n        private void AddDataTo(int frameIdx, string threadName, ThreadData data)\n        {\n            ThreadViewData threadViewData = null;\n            if (!this.viewData.TryGetValue(threadName, out threadViewData))\n            {\n                threadViewData = new ThreadViewData(threadName);\n                viewData.Add(threadName, threadViewData);\n            }\n            float totalMsec = 0.0f;\n            float idleMsec = 0.0f;\n            int totalCount = 0;\n            int idleCount = 0;\n            if (data.m_AllSamples != null)\n            {\n                foreach (var sample in data.m_AllSamples)\n                {\n                    if (sample.parent == null)\n                    {\n                        idleMsec += GetSumOfTimeInSampleChildren(sample, \"Idle\", ref idleCount);\n                        totalMsec += GetSumeOfTimeWithNamedSampleInChildren(sample, ref totalCount);// sample.timeUS / 1000.0f;\n                    }\n                }\n            }\n            threadViewData.AddMsec(frameIdx, totalMsec, idleMsec, totalCount, idleCount);\n        }\n\n        private float GetSumeOfTimeWithNamedSampleInChildren(ProfilerSample sample, ref int count)\n        {\n            float sum = 0.0f;\n            if (!string.IsNullOrEmpty(sample.sampleName))\n            {\n                count += 1;\n                return sample.timeUS / 1000.0f;\n            }\n            if (sample.children == null)\n            {\n                return sum;\n            }\n            foreach (var child in sample.children)\n            {\n                sum += GetSumeOfTimeWithNamedSampleInChildren(child, ref count);\n            }\n            return sum;\n        }\n\n        private float GetSumOfTimeInSampleChildren(ProfilerSample sample, string matchStr, ref int count)\n        {\n            float sum = 0.0f;\n            if (sample == null) { return sum; }\n            if (sample.sampleName == matchStr)\n            {\n                count += 1;\n                return sample.timeUS / 1000.0f;\n            }\n            if (sample.children == null)\n            {\n                return sum;\n            }\n\n            foreach (var child in sample.children)\n            {\n                sum += GetSumOfTimeInSampleChildren(child, matchStr, ref count);\n            }\n            return sum;\n        }\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            int frameNum = 0;\n            var threadViewDataList = new List<ThreadViewData>(viewData.Values);\n\n            foreach (var data in threadViewDataList)\n            {\n                if (data.threadName == FrameWholeDataSpecialKey)\n                {\n                    csvStringGenerator.AppendColumn(data.threadName).AppendColumn(\"\");\n                }\n                else\n                {\n                    csvStringGenerator.AppendColumn(data.threadName + \"(msec)\");\n                    csvStringGenerator.AppendColumn(\"idle(msec)\");\n                    csvStringGenerator.AppendColumn(\"working(msec)\");\n                    csvStringGenerator.AppendColumn(\"rootBlock\");\n                    csvStringGenerator.AppendColumn(\"idleBlock\").AppendColumn(\"\");\n                }\n                frameNum = ProfilerLogUtil.Max(data.maxFrame, frameNum);\n            }\n            csvStringGenerator.NextRow();\n\n            for (int i = 0; i < frameNum; ++i)\n            {\n                foreach (var data in threadViewDataList)\n                {\n                    int totalCnt, idleCnt;\n                    float total, idle;\n                    data.GetMSecData(i, out total, out idle, out totalCnt, out idleCnt);\n                    if (data.threadName == FrameWholeDataSpecialKey)\n                    {\n                        csvStringGenerator.AppendColumn(total).AppendColumn(\"\");\n                    }\n                    else\n                    {\n                        csvStringGenerator.AppendColumn(total).AppendColumn(idle).AppendColumn(total - idle);\n                        csvStringGenerator.AppendColumn(totalCnt).AppendColumn(idleCnt).AppendColumn(\"\");\n                    }\n                }\n                csvStringGenerator.NextRow();\n            }\n            return csvStringGenerator.ToString();\n        }\n        \n        protected override string FooterName\n        {\n            get\n            {\n                return \"_result.csv\";\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Editor/Analyzer/Impl/ThreadAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 2a8ca0b714cbc7044987ba7b2a4c42ef\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/UrpGpuSampleToFile .cs",
    "content": "﻿using System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\nusing System.Text;\nusing UTJ.ProfilerReader.BinaryData.Thread;\nusing UTJ.ProfilerReader.RawData.Protocol;\nusing System.Runtime.Remoting.Channels;\nusing System;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class UrpGPUSampleToFile : AnalyzeToTextbaseFileBase\n    {\n        public enum Category : int\n        {\n            Opaque = 0,\n            Transparent = 1,\n            Shadowmap = 2,\n            PostProcess = 3,\n            Other = 4\n        };\n\n        private struct GpuTimeInfo\n        {\n            public int time;\n            public int count;\n        }\n        private class FrameGpuTime\n        {\n            public int frameIdx;\n            public Dictionary<int, GpuTimeInfo> gpuTimeByCategory;\n\n            public void AddGpuSample(GPUTime gpuTime, int category)\n            {\n                if (gpuTimeByCategory == null)\n                {\n                    gpuTimeByCategory = new Dictionary<int, GpuTimeInfo>();\n                }\n                GpuTimeInfo time;\n                if (gpuTimeByCategory.TryGetValue(category, out time))\n                {\n                    time.time += gpuTime.gpuTimeInMicroSec;\n                    time.count += 1;\n                    gpuTimeByCategory[category] = time;\n                }\n                else\n                {\n                    time = new GpuTimeInfo { time = gpuTime.gpuTimeInMicroSec, count = 1 };\n                    gpuTimeByCategory.Add(category, time);\n                }\n            }\n        }\n\n        private List<FrameGpuTime> frameGpuTimes = new List<FrameGpuTime>();\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            FrameGpuTime frameGpuTime = new FrameGpuTime();\n            frameGpuTime.frameIdx = frameData.frameIndex;\n\n            foreach (var threadData in frameData.m_ThreadData) {\n                AddGpuSampleByThread(threadData, frameGpuTime);\n            }\n            this.frameGpuTimes.Add(frameGpuTime);\n        }\n\n        private void AddGpuSampleByThread(ThreadData thread, FrameGpuTime frameGpuTime)\n        {\n            if (thread == null) { return; }\n            if (thread.m_GPUTimeSamples == null) { return; }\n            foreach (var gpuSample in thread.m_GPUTimeSamples)\n            {\n                frameGpuTime.AddGpuSample(gpuSample, GetGpuCategoryByCpuSample(thread, gpuSample));\n            }\n        }\n        private int GetGpuCategoryByCpuSample(ThreadData thread, GPUTime gpuSample)\n        {\n            int category = (int)Category.Other;\n            var cpuSample = GetCpuSample(thread, gpuSample);\n            for (var current = cpuSample; current != null;current = current.parent)\n            {\n                if(current.sampleName == null) { continue; }\n\n                if (current.sampleName.EndsWith(\"Opaques\"))\n                {\n                    return (int)Category.Opaque;\n                }\n                else if (current.sampleName.EndsWith(\"Transparents\"))\n                {\n                    return (int)Category.Transparent;\n                }\n                else if (current.sampleName.EndsWith(\"ShadowMap\"))\n                {\n                    return (int)Category.Shadowmap;\n                }\n                else if (current.sampleName.Contains(\"PostProcessing\"))\n                {\n                    return (int)Category.PostProcess;\n                }\n            }\n            return category;\n        }\n\n        private ProfilerSample GetCpuSample(ThreadData thread, GPUTime gpuSample)\n        {\n            int idx = (int)gpuSample.relatedSampleIndex;\n            if(thread.m_AllSamples == null) { return null; }\n            if( idx < 0 || idx >= thread.m_AllSamples.Count)\n            {\n                return null;\n            }\n            ProfilerSample cpuSample = thread.m_AllSamples[idx];\n            return cpuSample;\n\n        }\n\n\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            csvStringGenerator.AppendColumn(\"frameIdx\");\n\n\n            foreach (var category in System.Enum.GetValues(typeof(Category))) \n            {\n                csvStringGenerator.AppendColumn(category.ToString() + \"(ms)\");\n            }\n            csvStringGenerator.AppendColumn(\"callNum\");\n            foreach (var category in System.Enum.GetValues(typeof(Category)))\n            {\n                csvStringGenerator.AppendColumn(category.ToString() + \"(calls)\");\n            }\n\n            csvStringGenerator.NextRow();\n            foreach( var gpuFrame in frameGpuTimes)\n            {\n                if (gpuFrame.gpuTimeByCategory == null) { continue; }\n                csvStringGenerator.AppendColumn(gpuFrame.frameIdx);\n\n                foreach (var category in System.Enum.GetValues(typeof(Category)))\n                {\n                    GpuTimeInfo val ;\n                    if(gpuFrame.gpuTimeByCategory.TryGetValue((int)category,out val))\n                    {\n                        csvStringGenerator.AppendColumn( (float)val.time / 1000.0f);\n                    }\n                    else\n                    {\n                        csvStringGenerator.AppendColumn(0);\n                    }\n                }\n                csvStringGenerator.AppendColumn(\"\");\n\n                foreach (var category in System.Enum.GetValues(typeof(Category)))\n                {\n                    GpuTimeInfo val;\n                    if (gpuFrame.gpuTimeByCategory.TryGetValue((int)category, out val))\n                    {\n                        csvStringGenerator.AppendColumn(val.count);\n                    }\n                    else\n                    {\n                        csvStringGenerator.AppendColumn(0);\n                    }\n                }\n\n                csvStringGenerator.NextRow();\n            }\n            return csvStringGenerator.ToString();\n        }\n        \n\n        protected override string FooterName\n        {\n            get\n            {\n                return \"_urp_gpu_sample.csv\";\n            }\n        }\n\n\n    }\n\n}"
  },
  {
    "path": "Editor/Analyzer/Impl/UrpGpuSampleToFile .cs.meta",
    "content": "fileFormatVersion: 2\nguid: 49f5a491901f9f646afcadc3c2c9dda7\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl/WorkerJobAnalyzeToFile.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UTJ.ProfilerReader.BinaryData;\n\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    public class WorkerJobAnalyzeToFile : AnalyzeToTextbaseFileBase\n    {\n        private class WorkerThreadSample\n        {\n            public string sampleName;\n            public float minMSec = float.MaxValue;\n            public float maxMsec = 0.0f;\n            public float sumMsec = 0.0f;\n            public int callNum = 0;\n\n            public WorkerThreadSample(string name)\n            {\n                this.sampleName = name;\n            }\n\n            public void Called(float msec)\n            {\n                minMSec = ProfilerLogUtil.Min(minMSec, msec);\n                maxMsec = ProfilerLogUtil.Max(maxMsec, msec);\n                sumMsec += msec;\n                ++callNum;\n            }\n        }\n        private void AddSampleData(string sampleName, float msec)\n        {\n            WorkerThreadSample sampleData = null;\n            if (!this.samples.TryGetValue(sampleName, out sampleData))\n            {\n                sampleData = new WorkerThreadSample(sampleName);\n                this.samples.Add(sampleName, sampleData);\n            }\n            sampleData.Called(msec);\n        }\n\n        private Dictionary<string, WorkerThreadSample> samples = new Dictionary<string, WorkerThreadSample>();\n\n\n        private void CollectThread(ThreadData thread)\n        {\n            if (thread.m_AllSamples == null) { return; }\n            foreach (var sample in thread.m_AllSamples)\n            {\n                if (sample.parent == null)\n                {\n                    CollectFromNamedChildren(sample);\n                }\n            }\n        }\n\n        private void CollectFromNamedChildren(ProfilerSample sample)\n        {\n            if (!string.IsNullOrEmpty(sample.sampleName))\n            {\n                AddSampleData(sample.sampleName, sample.timeUS / 1000.0f);\n                return;\n            }\n            if (sample.children == null)\n            {\n                return;\n            }\n            foreach (var child in sample.children)\n            {\n                CollectFromNamedChildren(child);\n            }\n            return;\n        }\n\n        public override void CollectData(ProfilerFrameData frameData)\n        {\n            // 特別枠で frameDataのＣＰＵ時間を追加\n            // 同一フレーム内に同じスレッド名が複数できるので…\n            Dictionary<string, int> threadNameCounter = new Dictionary<string, int>(8);\n            foreach (var thread in frameData.m_ThreadData)\n            {\n                if (thread.m_ThreadName == \"Worker Thread\" || thread.m_GroupName  == \"Job\" )\n                {\n                    CollectThread(thread);\n                }\n            }\n        }\n        /// <summary>\n        /// 結果書き出し\n        /// </summary>\n        protected override string GetResultText()\n        {\n            CsvStringGenerator csvStringGenerator = new CsvStringGenerator();\n            csvStringGenerator.AppendColumn(\"name\").AppendColumn(\"sum(msec)\").AppendColumn(\"call\").AppendColumn(\"min(msec)\").AppendColumn(\"max(msec)\").NextRow();\n\n            var sampleDataList = new List<WorkerThreadSample>(samples.Values);\n            sampleDataList.Sort((a, b) =>\n            {\n                if (a.sumMsec > b.sumMsec)\n                {\n                    return -1;\n                }\n                else if (a.sumMsec < b.sumMsec)\n                {\n                    return 1;\n                }\n                return 0;\n            });\n            foreach (var sampleData in sampleDataList)\n            {\n                csvStringGenerator.AppendColumn(sampleData.sampleName).\n                    AppendColumn(sampleData.sumMsec).\n                    AppendColumn(sampleData.callNum).\n                    AppendColumn(sampleData.minMSec).\n                    AppendColumn(sampleData.maxMsec);\n                csvStringGenerator.NextRow();\n            }\n\n            return csvStringGenerator.ToString();\n        }\n        \n        protected override string FooterName\n        {\n            get\n            {\n                return \"_worker.csv\";\n            }\n        }\n\n    }\n\n}"
  },
  {
    "path": "Editor/Analyzer/Impl/WorkerJobAnalyzeToFile.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1a89b4a11c81a764fbb5546d719a95cd\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/Impl.meta",
    "content": "fileFormatVersion: 2\nguid: 96fae94d084a0e44383e880362d47836\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer/ProfilingScope.cs",
    "content": "using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\nusing UnityEngine.Profiling;\n\nnamespace UTJ.ProfilerReader.Analyzer\n{\n    struct ProfilingScope : System.IDisposable\n    {\n        CustomSampler _sampler;\n        public ProfilingScope(CustomSampler sampler)\n        {\n            _sampler = sampler;\n            _sampler.Begin();\n        }\n        public void Dispose()\n        {\n            _sampler.End();\n        }\n    }\n}"
  },
  {
    "path": "Editor/Analyzer/ProfilingScope.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 364fed2e9c0775e448a30297b36b1b11\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Analyzer.meta",
    "content": "fileFormatVersion: 2\nguid: 0f01dcbdc9f147a4fbdcfe25cfc31014\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/CUI/CUIInterface.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UTJ.ProfilerReader.Analyzer;\nusing UnityEngine;\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace UTJ.ProfilerReader\n{\n    public class CUIInterface\n    {\n        const int NormalCode = 0;\n        const int TimeoutCode = 10;\n        const int ReadErrorCode = 11;\n\n        public enum CsvFileType\n        {\n\n        };\n\n        private static int timeoutSec = 0;\n        private static ILogReaderPerFrameData currentReader = null;\n        private static bool timeouted = false;\n\n        private static string overrideUnityVersion = null;\n\n\n        public static void SetTimeout(int sec)\n        {\n            Debug.Log(\"SetTimeout \" + sec);\n            timeoutSec = sec;\n            System.Threading.Thread th = new System.Threading.Thread(TimeOutExecute);\n            th.Start();\n        }\n        public static void TimeOutExecute()\n        {\n            System.Threading.Thread.Sleep(timeoutSec * 1000);\n            Debug.Log(\"Timeout!!!\");\n            currentReader.ForceExit();\n            timeouted = true;\n        }\n\n        public static void ProfilerToCsv()\n        {\n            var args = System.Environment.GetCommandLineArgs();\n            string inputFile = null;\n            string outputDir = null;\n            bool exitFlag = true;\n            bool logFlag = false;\n            bool isLegacyOutputDirPath = false;\n\n            for (int i = 0; i < args.Length; ++i)\n            {\n                if (args[i] == \"-PH.inputFile\")\n                {\n                    inputFile = args[i + 1];\n                    i += 1;\n                }\n                if (args[i] == \"-PH.outputDir\")\n                {\n                    outputDir = args[i + 1];\n                    i += 1;\n                }\n                if (args[i] == \"-PH.timeout\")\n                {\n                    SetTimeout(int.Parse(args[i + 1]));\n                    i += 1;\n                }\n                if( args[i] == \"-PH.overrideUnityVersion\")\n                {\n                    overrideUnityVersion = args[i + 1];\n                    i += 1;\n                }\n                if (args[i] == \"-PH.exitcode\")\n                {\n                    exitFlag = true;\n                }\n                if (args[i] == \"-PH.log\")\n                {\n                    logFlag = true;\n                }\n                if (args[i] == \"-PH.dirLegacy\") ;\n                {\n                    isLegacyOutputDirPath = true;\n                }\n            }\n            int code = ProfilerToCsv(inputFile, outputDir, logFlag, isLegacyOutputDirPath);\n            if(timeouted)\n            {\n                code = TimeoutCode;\n            }\n            if (exitFlag)\n            {\n                UnityEditor.EditorApplication.Exit(code);\n            }\n        }\n\n        public static int ProfilerToCsv(string inputFile,string outputDir,bool logFlag,bool isLegacyOutputDirPath)\n        {\n            int retCode = NormalCode;\n            if ( string.IsNullOrEmpty(outputDir))\n            {\n                if (isLegacyOutputDirPath)\n                {\n                    outputDir = Path.GetDirectoryName(inputFile);\n                }\n                else\n                {\n                    string file = Path.GetFileName(inputFile);\n                    outputDir = Path.Combine(Path.GetDirectoryName(inputFile), file.Replace('.', '_'));\n                }\n            }\n\n            var logReader = ProfilerLogUtil.CreateLogReader(inputFile);\n            currentReader = logReader;\n\n            List<IAnalyzeFileWriter> analyzeExecutes = AnalyzerUtil.CreateAnalyzerInterfaceObjects();\n\n            var frameData = logReader.ReadFrameData();\n            SetAnalyzerInfo(analyzeExecutes, logReader,outputDir,inputFile);\n\n            if ( frameData == null)\n            {\n                Debug.LogError(\"No FrameDataFile \" + inputFile);\n            }\n            // Loop and execute each frame\n            while (frameData != null)\n            {\n                try\n                {\n                    frameData = logReader.ReadFrameData();\n                    if (logFlag && frameData != null)\n                    {\n                        System.Console.WriteLine(\"ReadFrame:\" + frameData.frameIndex);\n                    }\n                }\n                catch (System.Exception e)\n                {\n                    retCode = ReadErrorCode;\n                    Debug.LogError(e);\n                }\n\n                if (frameData != null)\n                {\n                    List<Task> tasks = new List<Task>(analyzeExecutes.Count);\n                    foreach (var analyzer in analyzeExecutes)\n                    {\n                        var task = Task.Run(() =>\n                        {\n                            try\n                            {\n                                analyzer.CollectData(frameData);\n\n                            }\n                            catch (System.Exception e)\n                            {\n                                Debug.LogError(e);\n                            }\n                        });\n                        tasks.Add(task);\n                    }\n                    while (true)\n                    {\n                        bool isComplete = true;\n                        foreach (var task in tasks)\n                        {\n                            if (!task.IsCompleted)\n                            {\n                                isComplete = false;\n                                break;\n                            }\n                        }\n                        if (isComplete)\n                        {\n                            break;\n                        }\n                    }\n                }\n                System.GC.Collect();\n            }\n            foreach (var analyzer in analyzeExecutes)\n            {\n                analyzer.WriteResultFile(System.IO.Path.GetFileName(inputFile), outputDir);\n            }\n\n            return retCode;\n        }\n        private static void SetAnalyzerInfo(List<IAnalyzeFileWriter> analyzeExecutes,\n            ILogReaderPerFrameData logReader,\n            string outDir,string inFile)\n        {\n            ProfilerLogFormat format = ProfilerLogFormat.TypeData;\n            if (logReader.GetType() == typeof(UTJ.ProfilerReader.RawData.ProfilerRawLogReader))\n            {\n                format = ProfilerLogFormat.TypeRaw;\n            }\n            string unityVersion = Application.unityVersion;\n            if ( !string.IsNullOrEmpty(overrideUnityVersion))\n            {\n                unityVersion = overrideUnityVersion;\n            }\n            foreach (var analyzer in analyzeExecutes)\n            {\n                analyzer.SetInfo(format, unityVersion, logReader.GetLogFileVersion(), logReader.GetLogFilePlatform());\n                analyzer.SetFileInfo(inFile,outDir);\n            }\n        }\n    }\n}"
  },
  {
    "path": "Editor/CUI/CUIInterface.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 3f87dac947add4540b9b1f12ecfd9035\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/CUI.meta",
    "content": "fileFormatVersion: 2\nguid: 486ca37e5d486f34096200caa31394df\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/GUI/AnalyzeToCsvWindow.cs",
    "content": "﻿using UnityEngine;\nusing UnityEditor;\nusing System.Collections;\nusing System.Collections.Generic;\nusing UTJ.ProfilerReader.Analyzer;\nusing System.Reflection;\nusing System.IO;\nusing System.Threading.Tasks;\nusing System.Text;\nusing UnityEditor.Overlays;\n\nnamespace UTJ.ProfilerReader.UI {\n\n\n\n    public class AnalyzeToCsvWindow : EditorWindow\n    {\n\n\n        private class FileWriterFlag\n        {\n            public string name;\n            public System.Type type;\n            public bool flag;\n            \n        }\n\n        private List<FileWriterFlag> fileWriterFlags = new List<FileWriterFlag>();\n        private List<IAnalyzeFileWriter> analyzeExecutes = new List<IAnalyzeFileWriter>();\n        private ILogReaderPerFrameData logReader = null;\n        private bool isFirstFrame = true;\n        private Vector2 scrollPos;\n        private string filePath;\n\n        private string outputDir;\n        private string logfilename;\n        private bool isWindowExists;\n\n        private bool forceStopRequest = false;\n        private bool requestDialogFlag = false;\n\n        private bool isMultiThreadExecute = true;\n        private List<Task> analyzeTasks = new List<Task>(16);\n        private List<string> analyzeTaskNames = new List<string>(16);\n        private string taskStatus = \"\";\n        private GUIStyle uiStyle;\n\n\n\n        [MenuItem(\"Tools/UTJ/ProfilerReader/AnalyzeToCsv\")]\n        public static void CreateWindow()\n        {\n            EditorWindow.GetWindow<AnalyzeToCsvWindow>();\n        }\n\n        private void OnEnable()\n        {\n            this.uiStyle = new GUIStyle( );\n            this.uiStyle.normal.textColor = Color.red;\n            this.isWindowExists = true;\n            this.fileWriterFlags.Clear();\n            var types = AnalyzerUtil.GetInterfaceType<IAnalyzeFileWriter>();\n            foreach( var t in types)\n            {\n                this.fileWriterFlags.Add(new FileWriterFlag() { name = t.Name, type = t, flag = true });\n            }\n        }\n        private void OnDisable()\n        {\n            this.isWindowExists = false;\n        }\n\n        private void UpdateThread()\n        {\n            while (this.isWindowExists)\n            {\n                if(!ExecuteFrame()){\n                    return;\n                }\n            }\n        }\n\n        bool ExecuteFrame()\n        {\n            if (logReader == null)\n            {\n                return false;\n            }\n            try\n            {\n                var frameData = logReader.ReadFrameData();\n                if (isFirstFrame)\n                {\n                    InitOutputPathInfo();\n                    SetAnalyzerInfo(analyzeExecutes, logReader);\n                    isFirstFrame = false;\n                }\n                if (frameData == null || forceStopRequest)\n                {\n                    // write all result\n                    foreach (var analyzer in this.analyzeExecutes)\n                    {\n                        analyzer.WriteResultFile(logfilename, outputDir);\n                    }\n                    requestDialogFlag = true;\n                    logReader = null;\n                    return false;\n                }\n                foreach (var analyzer in this.analyzeExecutes)\n                {\n                    var task = Task.Run(() =>\n                    {\n                        try\n                        {\n                            analyzer.CollectData(frameData);\n                        }\n                        catch (System.Exception e)\n                        {\n                            Debug.LogError(e);\n                        }\n                    });\n                    analyzeTaskNames.Add(analyzer.GetType().Name);\n                    analyzeTasks.Add(task);\n                }\n                // waiting all tasks\n                var sb = new StringBuilder();\n                while (true)\n                {\n                    bool isDone = true;\n                    sb.Length = 0;\n                    for(int i = 0;i < analyzeTasks.Count;++i)\n                    {\n                        var task = analyzeTasks[i];\n                        if (!task.IsCompleted)\n                        {\n                            isDone = false;\n                            if(sb.Length > 0)\n                            {\n                                sb.Append(\"\\n\");\n                            }\n                            sb.Append(analyzeTaskNames[i]).Append(\"::\").Append(task.Status);\n                        }\n                    }\n                    taskStatus = sb.ToString();\n                    if (isDone)\n                    {\n                        break;\n                    }\n                }\n                taskStatus = \"\";\n                analyzeTasks.Clear();\n                analyzeTaskNames.Clear();\n\n                System.GC.Collect();\n\n            }\n            catch (System.Exception e)\n            {\n                logReader = null;\n                Debug.LogError(e);\n            }\n            return true;\n        }\n\n        private void DisplayDialog()\n        {\n            requestDialogFlag = false;\n            string dialogStr = \"Write to csv files\\n\";\n            foreach (var analyzer in this.analyzeExecutes)\n            {\n                dialogStr += analyzer.GetType() + \"\\n\";\n            }\n            EditorUtility.DisplayDialog(\"Result\", dialogStr, \"ok\");\n            analyzeExecutes.Clear();\n        }\n\n\n        void OnGUI()\n        {\n            EditorGUILayout.LabelField(\"Convert profiler log to csv\");\n            EditorGUILayout.BeginHorizontal();\n            if (string.IsNullOrEmpty(filePath))\n            {\n                EditorGUILayout.LabelField(\"Select File\");\n            }\n            else\n            {\n                EditorGUILayout.LabelField(this.filePath);\n            }\n            if (GUILayout.Button(\"File\", GUILayout.Width(40.0f)))\n            {\n                this.filePath = EditorUtility.OpenFilePanelWithFilters(\"\", \"Select BinaryLogFile\", new string[] { \"profiler log\", \"data,raw\" });\n            }\n\n            if (!IsExecute())\n            {\n                if (GUILayout.Button(\"Analyze\", GUILayout.Width(100)))\n                {\n                    if (string.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))\n                    {\n                        Debug.LogError(\"No such File \");\n                    }\n                    else\n                    {\n                        StartAnalyze();\n                    }\n                }\n            }\n            else\n            {\n                if (GUILayout.Button(\"ForceExit\", GUILayout.Width(100)))\n                {\n                    forceStopRequest = true;\n                }\n            }\n            EditorGUILayout.EndHorizontal();\n            if (IsExecute() )\n            {\n                uiStyle.alignment = TextAnchor.UpperLeft;\n                \n                EditorGUILayout.LabelField(\"Progress \" + logReader.Progress * 100.0f + \"%\");\n                EditorGUILayout.LabelField(this.taskStatus, uiStyle, GUILayout.Height(200));\n            }\n            else\n            {\n                for (int i = 0; i < fileWriterFlags.Count; ++i)\n                {\n                    EditorGUILayout.BeginHorizontal();\n                    this.fileWriterFlags[i].flag = EditorGUILayout.Toggle(this.fileWriterFlags[i].flag ,GUILayout.Width(20) );\n                    EditorGUILayout.LabelField(this.fileWriterFlags[i].name);\n                    EditorGUILayout.EndHorizontal();\n                }\n            }\n\n            EditorGUILayout.LabelField(\"The results are in csv file.\");\n        }\n\n        private void StartAnalyze()\n        {\n            logReader = ProfilerLogUtil.CreateLogReader(filePath);\n            isFirstFrame = true;\n            forceStopRequest = false;\n            analyzeExecutes.Clear();\n            for (int i = 0; i < fileWriterFlags.Count; ++i)\n            {\n                if (this.fileWriterFlags[i].flag)\n                {\n                    var analyzer = System.Activator.CreateInstance(fileWriterFlags[i].type) as IAnalyzeFileWriter;\n                    analyzeExecutes.Add(analyzer);\n                }\n            }\n            // start analyze\n            if (isMultiThreadExecute)\n            {\n                var thread = new System.Threading.Thread(this.UpdateThread);\n                thread.Start();\n            }\n        }\n\n\n        private void Update()\n        {\n            if (!isMultiThreadExecute)\n            {\n                this.ExecuteFrame();\n            }\n            if (IsExecute())\n            {\n                this.Repaint();\n            }\n            if (requestDialogFlag)\n            {\n                this.DisplayDialog();\n            }\n        }\n\n        private bool IsExecute()\n        {\n            return (logReader != null && 0.0f < logReader.Progress && logReader.Progress < 1.0f);\n        }\n\n        private void InitOutputPathInfo()\n        {\n            this.logfilename = Path.GetFileName(this.filePath);\n            this.outputDir = Path.Combine(Path.GetDirectoryName(this.filePath), logfilename.Replace('.', '_'));\n            if (!Directory.Exists(this.outputDir))\n            {\n                Directory.CreateDirectory(this.outputDir);\n            }\n        }\n\n        private void SetAnalyzerInfo(List<IAnalyzeFileWriter> analyzeExecutes, ILogReaderPerFrameData logReader)\n        {\n\n            ProfilerLogFormat format = ProfilerLogFormat.TypeData;\n            if (logReader.GetType() == typeof(UTJ.ProfilerReader.RawData.ProfilerRawLogReader))\n            {\n                format = ProfilerLogFormat.TypeRaw;\n            }\n            foreach (var analyzer in analyzeExecutes)\n            {\n                analyzer.SetInfo(format, Application.unityVersion, logReader.GetLogFileVersion(), logReader.GetLogFilePlatform());\n                analyzer.SetFileInfo(logfilename, this.outputDir);\n            }\n        }\n\n\n    }\n\n\n}"
  },
  {
    "path": "Editor/GUI/AnalyzeToCsvWindow.cs.meta",
    "content": "fileFormatVersion: 2\nguid: abd0154d324b92e4584511ce7086dea7\ntimeCreated: 1479298377\nlicenseType: Pro\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/GUI/LogAnalyzeWindow.cs",
    "content": "﻿using UnityEngine;\nusing UnityEditor;\nusing System.Collections;\nusing System.Collections.Generic;\nusing UTJ.ProfilerReader;\nusing UTJ.ProfilerReader.BinaryData;\nusing UTJ.ProfilerReader.RawData;\n\nnamespace UTJ.ProfilerReader.UI{\n    public class LogAnalyzeWindow : EditorWindow\n    {\n        private struct ColumnData\n        {\n            public ProfilerSample sample;\n            public int frameIndex;\n        }\n        public enum EConditionType\n        {\n            StartsWith,\n            Contains,\n            EndsWith,\n        }\n\n        // 表示条件\n        public enum ESampleCondition\n        {\n            Always,\n            ParentOnly,\n            ChildOnly,\n        }\n        private const int PagingNumber = 100;\n\n        private ILogReaderPerFrameData logReader = null;\n        private SampleDetailView treeView = new SampleDetailView();\n        private List<ColumnData> columnList = new List<ColumnData>();\n        private Vector2 scrollPos;\n        private string filePath;\n\n        private EConditionType stringCheckCondition;\n        private ESampleCondition sampleCondition;\n\n        private string sampleNameCondition;\n        private float conditionExecuteTime;\n        private int conditionAlloc;\n        private int pageIndex;\n\n\n        [MenuItem(\"Tools/UTJ/ProfilerReader/LogAnalyzer\")]\n        public static void CreateWindow()\n        {\n            EditorWindow.GetWindow<LogAnalyzeWindow>();\n        }\n\n        void OnEnable()\n        {\n        }\n\n        void Update()\n        {\n            try\n            {\n                if (logReader != null)\n                {\n                    var data = logReader.ReadFrameData();\n                    if (data == null) { return; }\n                    this.CollectData(data);\n                    System.GC.Collect();\n                    if (data == null)\n                    {\n                        logReader = null;\n                    }\n                    this.Repaint();\n                }\n            }\n            catch (System.Exception e)\n            {\n                logReader = null;\n                Debug.LogError(e);\n            }\n        }\n        void OnGUI()\n        {\n            EditorGUILayout.LabelField(\"Profiler BinLog Hack\");\n            EditorGUILayout.BeginHorizontal();\n            this.filePath = EditorGUILayout.TextField(this.filePath);\n            if (GUILayout.Button(\"File\", GUILayout.Width(40.0f)))\n            {\n                this.filePath = EditorUtility.OpenFilePanelWithFilters(\"\", \"Select BinaryLogFile\", new string[]{ \"profiler log\", \"data,raw\" });\n            }\n            EditorGUILayout.EndHorizontal();\n            {\n                EditorGUILayout.LabelField(\"Concition\");\n                EditorGUILayout.BeginHorizontal();\n                sampleNameCondition = EditorGUILayout.TextField(\"sample name \", sampleNameCondition);\n                this.stringCheckCondition = (EConditionType)EditorGUILayout.EnumPopup(this.stringCheckCondition);\n                EditorGUILayout.EndHorizontal();\n\n                EditorGUILayout.BeginHorizontal();\n                EditorGUILayout.LabelField(\"HierarchyMode\");\n                this.sampleCondition = (ESampleCondition)EditorGUILayout.EnumPopup(this.sampleCondition);\n                EditorGUILayout.EndHorizontal();\n\n                EditorGUILayout.BeginHorizontal();\n                this.conditionExecuteTime = EditorGUILayout.FloatField(\"Execute time(ms)\", this.conditionExecuteTime);\n                this.conditionAlloc = EditorGUILayout.IntField(\"Alloc(byte)\", conditionAlloc);\n                EditorGUILayout.EndHorizontal();\n            }\n\n            EditorGUILayout.BeginHorizontal();\n            if (!IsExecuting())\n            {\n\n                if (GUILayout.Button(\"Analyze\", GUILayout.Width(100)))\n                {\n                    this.pageIndex = 1;\n                    if (string.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))\n                    {\n                        Debug.LogError(\"No such File \");\n                    }\n                    else\n                    {\n                        logReader = ProfilerLogUtil.CreateLogReader(filePath);\n                        logReader.SetUnityVersion(Application.unityVersion);\n                        columnList.Clear();\n                    }\n                }\n            }\n            else\n            {\n                if (GUILayout.Button(\"Cancel\", GUILayout.Width(100)))\n                {\n                    logReader.ForceExit();\n                }\n            }\n            GUILayout.Label(\"\");\n            if (logReader != null && logReader.IsComplete)\n            {\n                if (GUILayout.Button(\"Write To CSV\", GUILayout.Width(100)))\n                {\n                    SaveToCsv();\n                }\n            }\n            EditorGUILayout.EndHorizontal();\n            // execute now\n            if (IsExecuting())\n            {\n                EditorGUILayout.LabelField(\"Progress \" + logReader.Progress * 100.0f + \"%\");\n            }\n            else\n            {\n                this.ONGUIResultList();\n                treeView.OnGUI();\n            }\n        }\n\n        private bool IsExecuting()\n        {\n            return (logReader != null && 0.0f < logReader.Progress && logReader.Progress < 1.0f);\n        }\n\n\n        private void ONGUIResultList()\n        {\n            EditorGUILayout.BeginHorizontal();\n            if( GUILayout.Button(\"<-\",GUILayout.Width(40)))\n            {\n                if (pageIndex > 1)\n                {\n                    --pageIndex;\n                }\n            }\n            var pageStr = EditorGUILayout.TextField(this.pageIndex.ToString(), GUILayout.Width(40));\n            int.TryParse(pageStr, out this.pageIndex);\n            EditorGUILayout.LabelField(\"/\" + (columnList.Count + PagingNumber - 1) / PagingNumber, GUILayout.Width(40));\n\n            if( GUILayout.Button(\"->\", GUILayout.Width(40)))\n            {\n                if (pageIndex + 1 <= (columnList.Count + PagingNumber-1) / PagingNumber)\n                {\n                    ++pageIndex;\n                }\n            }\n            EditorGUILayout.EndHorizontal();\n            this.scrollPos = EditorGUILayout.BeginScrollView(scrollPos, true, true);\n            EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true));\n            for(int i = (this.pageIndex -1) * PagingNumber; i< columnList.Count && i < (this.pageIndex) * PagingNumber; ++ i)\n            {\n                if( i < 0 || i > columnList.Count) { continue; }\n                ColumnData column = columnList[i];\n                var sample = column.sample;\n                EditorGUILayout.BeginHorizontal();\n                if (GUILayout.Button(\"More\", GUILayout.Width(40)))\n                {\n                    this.treeView.SetCurrentSample(sample);\n                }\n                string str = column.frameIndex + \"::\" + sample.sampleName + \"::\" + (sample.timeUS / 1000.0f) +\n                        \"ms Alloc:\";\n                if (sample.totalGcAlloc < 1024 * 10)\n                {\n                    str += sample.totalGcAlloc + \" Byte\";\n                }\n                else if (sample.totalGcAlloc < 1024 * 1024 * 10)\n                {\n                    str += (sample.totalGcAlloc / 1024) + \" KByte\";\n                }\n                else\n                {\n                    str += (sample.totalGcAlloc / 1024 / 1024) + \" MByte\";\n                }\n\n                EditorGUILayout.LabelField(str);\n                EditorGUILayout.EndHorizontal();\n            }\n            EditorGUILayout.EndVertical();\n            EditorGUILayout.EndScrollView();\n        }\n\n        private void CollectData(ProfilerFrameData frameData)\n        {\n            var mainThread = frameData.MainThread;\n            if( mainThread == null || mainThread.m_AllSamples == null ) { return; }\n            List<ColumnData> hitInThisFrame = new List<ColumnData>();\n            foreach (var sample in mainThread.m_AllSamples)\n            {\n                if (ChcekSearchCondition(sample))\n                {\n                    ColumnData data;\n                    data.sample = sample;\n                    data.frameIndex = frameData.frameIndex;\n                    hitInThisFrame.Add(data);\n                }\n            }\n\n            foreach (var hit in hitInThisFrame)\n            {\n                switch (this.sampleCondition)\n                {\n                    case ESampleCondition.Always:\n                        this.columnList.Add(hit);\n                        break;\n                    case ESampleCondition.ChildOnly:\n                        if (!IsChildExists(hit, hitInThisFrame))\n                        {\n                            this.columnList.Add(hit);\n                        }\n                        break;\n                    case ESampleCondition.ParentOnly:\n                        if (!IsParentExists(hit, hitInThisFrame))\n                        {\n                            this.columnList.Add(hit);\n                        }\n                        break;\n                }\n            }\n        }\n        private bool IsChildExists(ColumnData column, List<ColumnData> list)\n        {\n            foreach (var target in list)\n            {\n                if (target.sample != column.sample && IsParent(column.sample, target.sample))\n                {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        private bool IsParentExists(ColumnData column, List<ColumnData> list)\n        {\n            foreach (var target in list)\n            {\n                if (target.sample != column.sample && IsParent(target.sample, column.sample))\n                {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        private bool IsParent(ProfilerSample parent, ProfilerSample child)\n        {\n            for (ProfilerSample current = child.parent; current != null; current = current.parent)\n            {\n                if (current == parent)\n                {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n\n        private bool ChcekSearchCondition(ProfilerSample sample)\n        {\n            if (sample.totalGcAlloc < this.conditionAlloc)\n            {\n                return false;\n            }\n            if (sample.timeUS / 1000.0f < this.conditionExecuteTime)\n            {\n                return false;\n            }\n            if (string.IsNullOrEmpty(this.sampleNameCondition))\n            {\n                return true;\n            }\n            switch (this.stringCheckCondition)\n            {\n                case EConditionType.Contains:\n                    return sample.sampleName.Contains(this.sampleNameCondition);\n                case EConditionType.StartsWith:\n                    return sample.sampleName.StartsWith(this.sampleNameCondition);\n                case EConditionType.EndsWith:\n                    return sample.sampleName.EndsWith(this.sampleNameCondition);\n            }\n            return false;\n        }\n\n        void OnDisable()\n        {\n        }\n\n        // CSV保存を押したときの処理\n        private void SaveToCsv()\n        {\n            if (this.columnList == null || this.columnList.Count == 0)\n            {\n                EditorUtility.DisplayDialog(\"No Result\", \"There are no results.Please analyze before.\", \"OK\");\n                return;\n            }\n            if (0.0f < logReader.Progress && logReader.Progress < 1.0f)\n            {\n                EditorUtility.DisplayDialog(\"Progress\", \"Now executing...Wait a moment...\", \"OK\");\n                return;\n            }\n            string savePath = EditorUtility.SaveFilePanel(\"CSV file\", \"\", \"result\", \"csv\");\n            if (string.IsNullOrEmpty(savePath))\n            {\n                return;\n            }\n            WriteCsv(savePath);\n        }\n\n        // 実際にファイルを書き込むところ\n        private void WriteCsv(string path)\n        {\n            var sb = new System.Text.StringBuilder();\n            sb.Append(\"frame,SampleName,executeTime(ms),memoryAlloc(byte)\\n\");\n            foreach (var column in columnList)\n            {\n                if (column.sample == null) { continue; }\n                sb.Append(column.frameIndex).Append(\",\");\n                // コンマあると\n                sb.Append(column.sample.sampleName.Replace(',', '_')).Append(\",\");\n                sb.Append(column.sample.timeUS / 1000.0f).Append(\",\");\n                sb.Append(column.sample.totalGcAlloc).Append(\",\");\n                sb.Append(\"\\n\");\n            }\n\n            System.IO.File.WriteAllText(path, sb.ToString());\n            EditorUtility.DisplayDialog(\"Complete to write result\",\"Save result to\"+ path , \"OK\");\n\n        }\n    }\n\n\n\n    public class SampleDetailView\n    {\n\n        private ProfilerSample currentSample;\n        private Vector2 scrollPos;\n        private Dictionary<ProfilerSample, bool> openList;\n        private System.Text.StringBuilder stringBuilder;\n        private Dictionary<uint, int> allocateBlock;\n        private string[] guiTabStr = new string[] { \"Children\", \"Memory\" };\n\n        private int guiTabSelect;\n\n        public SampleDetailView()\n        {\n            openList = new Dictionary<ProfilerSample, bool>();\n            stringBuilder = new System.Text.StringBuilder();\n        }\n\n        public void SetCurrentSample(ProfilerSample sample)\n        {\n            openList.Clear();\n            this.currentSample = sample;\n            scrollPos = Vector2.zero;\n            if (sample != null)\n            {\n                allocateBlock = sample.GetBlockAllocCount();\n            }\n        }\n\n        public void OnGUI()\n        {\n            if (this.currentSample == null)\n            {\n                EditorGUILayout.BeginVertical();\n                EditorGUILayout.LabelField(\"Not Select\");\n                EditorGUILayout.EndVertical();\n                return;\n            }\n            EditorGUILayout.LabelField(currentSample.fullSampleName);\n            if (GUILayout.Button(\"Close\", GUILayout.Width(60)))\n            {\n                this.SetCurrentSample(null);\n                return;\n            }\n            this.guiTabSelect = GUILayout.Toolbar(this.guiTabSelect, this.guiTabStr);\n\n            scrollPos = EditorGUILayout.BeginScrollView(scrollPos, true, true, GUILayout.MinHeight(300));\n\n            switch (this.guiTabSelect)\n            {\n                case 0:\n                    ChildrenDraw(this.currentSample);\n                    break;\n                case 1:\n                    AllocateBlockListDraw(); // test\n                    break;\n            }\n\n            EditorGUILayout.EndScrollView();\n        }\n\n        private void ChildrenDraw(ProfilerSample sample)\n        {\n            if (sample == null) { return; }\n            this.stringBuilder.Length = 0;\n            this.stringBuilder.Append(sample.sampleName).Append(\"  \").Append((sample.timeUS / 1000.0f)).Append(\"ms Alloc:\").Append(sample.totalGcAlloc).Append(\" Byte\");\n            string outputStr = this.stringBuilder.ToString();\n\n            //        style.contentOffset = new Vector2(sample.hierarchyLevel * 10.0f, 0.0f);\n\n            bool isOpen = false;\n            if (sample.children != null)\n            {\n                GUIStyle style = new GUIStyle(EditorStyles.foldout);\n                style.margin.left = (sample.hierarchyLevel - currentSample.hierarchyLevel) * 20;\n                if (openList.TryGetValue(sample, out isOpen))\n                {\n                    bool openVal = EditorGUILayout.Foldout(isOpen, outputStr, style);\n                    if (openVal != isOpen) { openList[sample] = openVal; }\n                    if (isOpen)\n                    {\n                        foreach (var child in sample.children)\n                        {\n                            ChildrenDraw(child);\n                        }\n                    }\n                }\n                else\n                {\n                    openList.Add(sample, false);\n                    EditorGUILayout.Foldout(isOpen, outputStr, style);\n                }\n            }\n            else\n            {\n                GUIStyle style = new GUIStyle(EditorStyles.label);\n                style.padding.left = (sample.hierarchyLevel - currentSample.hierarchyLevel) * 20;\n                EditorGUILayout.LabelField(outputStr, style);\n            }\n        }\n\n        private void AllocateBlockListDraw()\n        {\n            if (allocateBlock == null) { return; }\n            EditorGUILayout.LabelField(\"total Memory \" + this.currentSample.totalGcAlloc + \" Byte\");\n            EditorGUILayout.Space();\n            List<uint> keys = new List<uint>(allocateBlock.Keys);\n            keys.Sort();\n            keys.Reverse();\n            foreach (var key in keys)\n            {\n                EditorGUILayout.LabelField(key + \" Byte X \" + allocateBlock[key]);\n            }\n        }\n\n\n        private void ParentGUIDraw(ProfilerSample sample)\n        {\n            if (sample == null) { return; }\n            ParentGUIDraw(sample.parent);\n            EditorGUILayout.LabelField(sample.sampleName);\n        }\n    }\n}"
  },
  {
    "path": "Editor/GUI/LogAnalyzeWindow.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 0b7140a5b12e4764fa5245c6e12d476f\ntimeCreated: 1479298377\nlicenseType: Pro\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/GUI/language/LanguageEn.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\n\nnamespace UTJ.ProfilerReader.UI\n{\n    public class LanguageEn : LanguageInterface\n    {\n\n        protected override void CreateDictionary() {\n        }\n    }\n}\n"
  },
  {
    "path": "Editor/GUI/language/LanguageEn.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 8abc955aa69cb5a45a48d1c754c65a77\ntimeCreated: 1516345952\nlicenseType: Pro\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/GUI/language/LanguageInterface.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\nnamespace UTJ.ProfilerReader.UI\n{\n    public abstract class LanguageInterface\n    {\n        private static LanguageInterface instance;\n\n        protected abstract void CreateDictionary();\n    }\n}\n"
  },
  {
    "path": "Editor/GUI/language/LanguageInterface.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 68a8ada8059764945b73502b7a916297\ntimeCreated: 1516345952\nlicenseType: Pro\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/GUI/language/LanguageJa.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\nnamespace UTJ.ProfilerReader.UI\n{\n    public class LanguageJa : LanguageInterface\n    {\n        protected override void CreateDictionary()\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "Editor/GUI/language/LanguageJa.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 285da0058b5be6944b84589f7071b118\ntimeCreated: 1516345952\nlicenseType: Pro\nMonoImporter:\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/GUI/language.meta",
    "content": "fileFormatVersion: 2\nguid: 8e7a70037606f1944a544856de86e8c8\nfolderAsset: yes\ntimeCreated: 1516345932\nlicenseType: Pro\nDefaultImporter:\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/GUI.meta",
    "content": "fileFormatVersion: 2\nguid: 105db1c87ad9d724dbcb5c713dc1338e\nfolderAsset: yes\ntimeCreated: 1478603637\nlicenseType: Pro\nDefaultImporter:\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/UTJProfileReader.dll.meta",
    "content": "fileFormatVersion: 2\nguid: 7b17b1edfad53ec42b71e81a27087216\nPluginImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  iconMap: {}\n  executionOrder: {}\n  defineConstraints: []\n  isPreloaded: 0\n  isOverridable: 1\n  isExplicitlyReferenced: 0\n  validateReferences: 1\n  platformData:\n  - first:\n      Any: \n    second:\n      enabled: 0\n      settings: {}\n  - first:\n      Editor: Editor\n    second:\n      enabled: 1\n      settings:\n        DefaultValueInitialized: true\n  - first:\n      Windows Store Apps: WindowsStoreApps\n    second:\n      enabled: 0\n      settings:\n        CPU: AnyCPU\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/Utj.ProfilerReader.Editor.asmdef",
    "content": "{\n    \"name\": \"UTJ.ProfilerReader.Editor\",\n    \"references\": [\n        \"UTJ.ProfilerReader.Core\"\n    ],\n    \"optionalUnityReferences\": [],\n    \"includePlatforms\": [\n        \"Editor\"\n    ],\n    \"excludePlatforms\": [],\n    \"allowUnsafeCode\": false,\n    \"overrideReferences\": false,\n    \"precompiledReferences\": [],\n    \"autoReferenced\": true,\n    \"defineConstraints\": []\n}"
  },
  {
    "path": "Editor/Utj.ProfilerReader.Editor.asmdef.meta",
    "content": "fileFormatVersion: 2\nguid: 5298c21b9b9dc8043a4297316264695f\nAssemblyDefinitionImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor/UtjProfilerInitializer.cs",
    "content": "﻿using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\nnamespace UTJ.ProfilerReader\n{\n    public class UtjProfilerInitializer \n    {\n        [UnityEditor.InitializeOnLoadMethod]\n        public static void Init()\n        {\n            ProfilerLogUtil.logErrorException = (e) => {\n            //    Debug.LogError(e);\n            };\n            ProfilerLogUtil.logErrorString = (str) => {\n                //    Debug.LogError(str);\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "Editor/UtjProfilerInitializer.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ad49b5af4070f2a4dbdea0ed31314305\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Editor.meta",
    "content": "fileFormatVersion: 2\nguid: 17970b62d246c2a4bb30ed8b06ac53cf\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "LICENSE.md",
    "content": "Profiler Reader\nCopyright (c) 2017-2018 Unity Technologies Japan\n\nLicensed under the Unity Companion License for Unity-dependent projects--see Unity Companion License.\n\nUnless expressly provided otherwise, the Software under this license is made available strictly on an gAS ISh BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions."
  },
  {
    "path": "LICENSE.md.meta",
    "content": "fileFormatVersion: 2\nguid: 3fc50eb3859c8a54cac1595ff61a265f\nTextScriptImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "README.ja.md",
    "content": "# ProfilerReader\nvt@C[̃Ot@C͂c[ł<br />\nRead this in other languages: [English](README.md), {<br />\n\n## Tv\ñc[ \"Unity Profiler\".\nFor example, generate csv files that shows Samples allocating many Managed Heap from \"Unity Profiler\" binary log.\n\n## Ήo[W\n2019.4 / 2020.3/2021.1/2021.2/2021.3/2022.2/2022.3\n<br/>2022.1 skip\n\n## Filter@\\\nuTools->UTJ->ProfilerReader->AnalyzeToCsvvŉLEBhEo܂B<br />\n![alt text](Documentation~/img/ProfilerReaderFilter.png)\n<br />\n1.vt@C[̃Ow肵܂<br />\n2.Tv̏w肵܂<br />\n3.ɍTv܂<br />\n4.ɍTv̌ʂ\\܂<br />\n5.ʂCSVɏo܂B<br />\n\n<br />\n\n## CSV@\\\n### GUIɂ\nuTools->UTJ->ProfilerReader->AnalyzeToCsvvŉLEBhEo܂B<br />\n![alt text](Documentation~/img/ProfilerLogToCsv.png)\n\n<br />\nWindowłCSVꂽT}[𐶐܂B<br />\n1.osʂ̎ws܂B<br />\n2.Profiler̃Ot@Cw肵܂B<br />\n3.͂s܂<br />\n\n### CUIł̃Tv\nUnity.exe -batchMode -projectPath \"ProjectPath\" -logFile .\\Editor.log -executeMethod UTJ.ProfilerReader.CUIInterface.ProfilerToCsv -PH.inputFile \"Binary logFile(.data/.raw)\" -PH.timeout 2400 -PH.log\n\noCiOt@CƓꏊɃTutH_쐬ACSVt@C܂B\n\n## CSV Files:\nCSt@ĆÃt@CɃtb^[tt@Cŏo͂܂B<br />\nL̂悤Ȍ`CSV͂o܂<br />\n\nuxxx_mainThread_frame.csvv<br />\nt[̃CXbhł̃JeSʂCPŨׂXg\n<br />\nuxxx_gc_result.csvv<br />\nŜʂGCmی̃Xg\n<br />\nuxxx_gpu_sample.csvv<br />\nProfilerGPUڂt[ɃJeSʂɏo郊Xg\n<br />\nuxxx_main_self.csvv<br />\nŜʂăTvʂCPU׃Xg\n<br />\nuxxx_memory.csvv<br />\nProfilerMemoryڂt[ɏoXg\n<br />\nuxxx_rendering.csvv<br />\nProfilerRenderingڂt[ɏoXg\n<br />\nuxxx_renderthread.csvv<br />\nRenderThread̏󋵂t[ɏoXg\n<br />\nuxxx_result.csvv<br />\nt[Thread̏󋵃Xg\n<br />\nuxxx_shader_compile.csvv<br />\nShaderRpC󋵂oXg\n<br />\nuxxx_urp_gpu_sample.csvv<br />\nGPUڂUniversal RPɏoXg\n<br />\nuxxx_worker.csvv<br />\nWorkerThread̏󋵂oXg\n<br />\n\n"
  },
  {
    "path": "README.ja.md.meta",
    "content": "fileFormatVersion: 2\nguid: c0d2319c301d3374bafab003c7b9ff5a\nTextScriptImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "README.md",
    "content": "﻿# ProfilerReader\nTools for analyze profiler log data.<br />\nRead this in other languages: English, [日本語](README.ja.md)<br />\n\n## Summary\nWith this tool, you can analyze the binary log of \"Unity Profiler\".\nFor example, generate csv files that shows Samples allocating many Managed Heap from \"Unity Profiler\" binary log.\n\n## Avalable versions\n2019.4 / 2020.3/2021.1/2021.2/2021.3/2022.2/2022.3\n<br/>2022.1 skip\n\n## Filter Search\nCall \"Tools->UTJ->ProfilerReader->AnalyzeToCsv\" and then this window will be displayed.<br />\n![alt text](Documentation~/img/ProfilerReaderFilter.png)\n<br />\n1.Set Profiler log file.<br />\n2.Set Conditions to search samples.<br />\n3.Execute Analyze<br />\n4.The results are here<br />\n5.Write the results to csv file.<br />\n\n## CSV Feature\n### GUI\nCall \"Tools->UTJ->ProfilerReader->AnalyzeToCsv\" and then this window will be displayed.<br />\n![alt text](Documentation~/img/ProfilerLogToCsv.png)\n\n<br />\nThis tool generate summarized csv files.<br />\n1.Select the categories to generate csv files.<br />\n2.Set Profler log File.<br />\n3.Execute Analyze<br />\n\n### CUI Sample\nUnity.exe -batchMode -projectPath \"ProjectPath\" -logFile .\\Editor.log -executeMethod UTJ.ProfilerReader.CUIInterface.ProfilerToCsv -PH.inputFile \"Binary logFile(.data/.raw)\" -PH.timeout 2400 -PH.log\n\nAnd some csv file will be generated at subfolder for binary data.\n\n\n## CSV Files:\nThis tool generate csv files with footer name.<br />\nThese are samples.<br />\n\n -\"xxx_mainThread_frame.csv\"<br />\nThe CPU stats by category in each fraemes.\n<br />\n -\"xxx_gc_result.csv\"<br />\nThe list that shows \"GC.Alloc\".\n<br />\n -\"xxx_gc_detail.csv\"<br />\nThe list of \"GC.Alloc\" and with Callstackinfo.\n<br />\n -\"xxx_gpu_sample.csv\"<br />\nThe list about GPU status in each frames .\n<br />\n -\"xxx_main_self.csv\"<br />\nThe list about CPU Samples.\n<br />\n -\"xxx_memory.csv\"<br />\nThe list about Memory status in each frames .\n<br />\n -\"xxx_rendering.csv\"<br />\nThe list about Rendering status in each frames .\n<br />\n -\"xxx_renderthread.csv\"<br />\nThe list about RenderThread status in each frames .\n<br />\n -\"xxx_result.csv\"<br />\nThe list about threads status in each frames .\n<br />\n -\"xxx_shader_compile.csv\"<br />\nThe list that shows Shader Compiling.\n<br />\n -\"xxx_urp_gpu_sample.csv\"<br />\nThe list about GPU for Universal RP.\n<br />\n -\"xxx_worker.csv\"<br />\nThe list about workerThread status.\n<br />\n - \"xxx_jitInfos.csv\"<br />\nThe list of callstack symbol infos.( should enable \"Profiler.enableAllocationCallstacks\").\n<br />\n"
  },
  {
    "path": "README.md.meta",
    "content": "fileFormatVersion: 2\nguid: 2c6b5239c79879f4cb86ecc915d6d29f\nTextScriptImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"com.utj.profilerreader\",\n  \"displayName\": \"Profiler Reader\",\n  \"version\": \"0.8.2-preview\",\n  \"unity\": \"2018.1\",\n  \"description\": \"read profiler log data package\",\n  \"keywords\": [\n    \"profiler\"\n  ],\n  \"category\": \"profiler\"\n}"
  },
  {
    "path": "package.json.meta",
    "content": "fileFormatVersion: 2\nguid: fbdf912d26e1f004587772ecc03857cb\nTextScriptImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  }
]