Esempio n. 1
0
        public void ProcessDataStream()
        {
            CultureInfo decimalCulture          = new CultureInfo("en-US");
            Regex       callstackAddressesRegex = new Regex(@"0x[0-9|a-f|A-F]*");

            List <KeyValuePair <string, EItemType> > newmds = new List <KeyValuePair <string, EItemType> >();
            FrameRecordPathCollection paths = new FrameRecordPathCollection();

            while (!m_logDataStream.IsEndOfStream)
            {
                if (m_logDataStream.Peek() == '<')
                {
                    ReadMetaData();
                    continue;
                }

                if (m_logLineDescriptors.Count == 0)
                {
                    m_logDataStream.ReadLine();
                    continue;
                }

                FrameRecordValues values          = new FrameRecordValues(paths);
                float             frameTimeInS    = 0.0f;
                MemoryStream      screenshotImage = null;
                List <UserMarker> userMarkers     = new List <UserMarker>();
                List <Callstack>  callstacks      = new List <Callstack>();

                foreach (PerfStatLogLineDescriptor lld in m_logLineDescriptors)
                {
                    string line = m_logDataStream.ReadLine();

                    if (line == null)
                    {
                        // it looks like the log's broken
                        break;
                    }

                    MatchCollection lineElements = lld.m_regex.Matches(line);

                    foreach (Match lineElement in lineElements)
                    {
                        string frameTimeValue = lineElement.Groups["frameTimeInS"].Value;
                        if (frameTimeValue.Length > 0)
                        {
                            frameTimeInS = (float)Convert.ToDouble(frameTimeValue, decimalCulture);
                        }

                        string path = lld.m_path;

                        foreach (PerfStatFrameElement fe in lld.m_formatElements)
                        {
                            string valueString = lineElement.Groups[fe.m_name].Value;

                            if (fe.m_type == EFrameElementType.String)
                            {
                                if (!valueString.StartsWith("'") || !valueString.EndsWith("'"))
                                {
                                    throw new Exception("strings need to be surrounded by 's");
                                }

                                valueString = valueString.Substring(1, valueString.Length - 2);
                            }

                            if (fe.m_name.Equals("path"))
                            {
                                path = path.Replace("$", valueString);
                            }
                            else
                            {
                                switch (fe.m_type)
                                {
                                case EFrameElementType.Float:
                                case EFrameElementType.Int:
                                    float  value    = string.Compare(valueString, "1.#QNAN0") == 0 ? 1.0f : (float)Convert.ToDouble(valueString, decimalCulture);
                                    string itemname = string.Intern(path + fe.m_name);
                                    values[itemname] += value;                                                  // += as there may be duplicate records per frame
                                    newmds.Add(new KeyValuePair <string, EItemType>(itemname, fe.m_type == EFrameElementType.Float ? EItemType.Float : EItemType.Int));
                                    break;

                                case EFrameElementType.B64Texture:
                                    if (screenshotImage != null)
                                    {
                                        throw new Exception("multiple screenshots found for a frame");
                                    }

                                    if (valueString.Length > 0)
                                    {
                                        try
                                        {
                                            byte[] bm = Convert.FromBase64String(valueString);
                                            screenshotImage = ImageProcessor.CreateImageStreamFromScreenshotBytes(bm);
                                        }
                                        catch (System.Exception)
                                        {
                                        }
                                    }

                                    break;

                                case EFrameElementType.String:
                                    string userMarkersInitialPath = "/UserMarkers/";
                                    string callstacksInitialPath  = "/Callstacks/";

                                    if (path.StartsWith(userMarkersInitialPath))
                                    {
                                        string     pathNoEndSlash = path.TrimEnd(new char[] { '/' });                                                   // old format compatibility
                                        UserMarker userMarker     = new UserMarker(pathNoEndSlash, valueString);
                                        userMarkers.Add(userMarker);
                                    }
                                    else if (path.StartsWith(callstacksInitialPath))
                                    {
                                        Callstack       callstack        = new Callstack(path.Substring(callstacksInitialPath.Length));
                                        MatchCollection addressesMatches = callstackAddressesRegex.Matches(valueString);

                                        foreach (Match addressMatch in addressesMatches)
                                        {
                                            UInt32 address = Convert.ToUInt32(addressMatch.Value, 16);
                                            callstack.m_functions.Add(GetSymbolNameFromAddress(address));
                                        }

                                        callstack.m_functions.Reverse();

                                        callstacks.Add(callstack);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }

                FrameRecord fr = new FrameRecord(m_logData.FrameRecords.Count, frameTimeInS, screenshotImage, m_logData.CreateNewFrameRecordValues(values), userMarkers, callstacks);
                m_logData.AddFrameRecord(fr, newmds);
            }

            foreach (var resolver in m_symbolResolvers)
            {
                resolver.Dispose();
            }

            m_symbolResolvers.Clear();
        }
Esempio n. 2
0
        public void ProcessDataStream()
        {
            CultureInfo decimalCulture          = new CultureInfo("en-US");
            Regex       callstackAddressesRegex = new Regex(@"0x[0-9|a-f|A-F]*");

            IIntervalSink[] ivSinks = new IIntervalSink[] {
                new StreamingIntervalSink(m_logData),
                new StreamingObjectSink(m_logData, "/Objects", 111),
                new StreamingTextureSink(m_logData, "/Textures", 116),
            };
            EventReader eventReader = new EventReader(ivSinks);

            try
            {
                //Endian
                byte[]  endianByte = m_logDataStream.ReadBytes(1);
                EEndian endian     = (EEndian)endianByte[0];
                m_logDataStream.SetEndian(endian);

                //Version
                UInt32 version = m_logDataStream.ReadUInt32();

                if (version > STATOSCOPE_BINARY_VERSION)
                {
                    throw new Exception("Binary file version mismatch");
                }

                m_logVersion = version;

                //Using string pool?
                m_bUsingStringPool = m_logDataStream.ReadBool();

                List <KeyValuePair <string, EItemType> > newmds = new List <KeyValuePair <string, EItemType> >();
                FrameRecordPathCollection paths = new FrameRecordPathCollection();

                while (!m_logDataStream.IsEndOfStream)
                {
                    // header present
                    if (m_logDataStream.ReadBool())
                    {
                        // modules present
                        if (m_logDataStream.ReadBool())
                        {
                            ReadModules();
                        }

                        ReadFormat();
                    }

                    //FRAME RECORD BEGIN
                    FrameRecordValues values          = new FrameRecordValues(paths);
                    float             frameTimeInS    = 0.0f;
                    MemoryStream      screenshotImage = null;
                    List <UserMarker> userMarkers     = new List <UserMarker>();
                    List <Callstack>  callstacks      = new List <Callstack>();

                    //check for fps or screen shot
                    float frameTimeValue = m_logDataStream.ReadFloat();

                    if (frameTimeValue > 0)
                    {
                        frameTimeInS = (float)Convert.ToDouble(frameTimeValue, decimalCulture);
                    }

                    EFrameElementType type = ReadFrameElementType();

                    if (type == EFrameElementType.B64Texture)
                    {
                        //process texture
                        int    size            = m_logDataStream.ReadInt32();
                        byte[] screenShotBytes = m_logDataStream.ReadBytes(size);
                        screenshotImage = ImageProcessor.CreateImageStreamFromScreenshotBytes(screenShotBytes);
                    }

                    //On to specific data groups
                    foreach (PerfStatLogLineDescriptor lld in m_logLineDescriptors)
                    {
                        //number of stats, so records have a variable number of entries, like frame profiler
                        int nStats = m_logDataStream.ReadInt32();

                        for (int i = 0; i < nStats; i++)
                        {
                            string path = lld.m_path;

                            foreach (PerfStatFrameElement fe in lld.m_formatElements)
                            {
                                if (fe.m_type == EFrameElementType.String && fe.m_name.Equals("path"))
                                {
                                    // Replace first occurrence of "$" in path with its placeholder value
                                    string        valueString      = ReadString();
                                    StringBuilder sbModifiedString = new StringBuilder(path);
                                    sbModifiedString.Replace("$", valueString, path.IndexOf("$"), 1);
                                    path = sbModifiedString.ToString();
                                }
                                else
                                {
                                    switch (fe.m_type)
                                    {
                                    case EFrameElementType.Float:
                                    {
                                        float  value    = m_logDataStream.ReadFloat();
                                        string itemname = path + fe.m_name;
                                        values[itemname] += value;                                                              // += as there may be duplicate records per frame
                                        newmds.Add(new KeyValuePair <string, EItemType>(itemname, EItemType.Float));
                                    }
                                    break;

                                    case EFrameElementType.Int:
                                    {
                                        int    value    = m_logDataStream.ReadInt32();
                                        string itemname = path + fe.m_name;
                                        values[itemname] += (float)value;                                                               // += as there may be duplicate records per frame
                                        newmds.Add(new KeyValuePair <string, EItemType>(itemname, EItemType.Int));
                                    }
                                    break;

                                    case EFrameElementType.B64Texture:
                                        throw new Exception("Screen shot in frame profiler not supported");
                                    //break;

                                    case EFrameElementType.String:
                                        string userMarkersInitialPath = "/UserMarkers/";
                                        string callstacksInitialPath  = "/Callstacks/";

                                        string valueString = ReadString();

                                        if (path.StartsWith(userMarkersInitialPath))
                                        {
                                            string     pathNoEndSlash = path.TrimEnd(new char[] { '/' });                                                       // old format compatibility
                                            UserMarker userMarker     = new UserMarker(pathNoEndSlash, valueString);
                                            userMarkers.Add(userMarker);
                                        }
                                        else if (path.StartsWith(callstacksInitialPath))
                                        {
                                            Callstack       callstack        = new Callstack(path.Substring(callstacksInitialPath.Length));
                                            MatchCollection addressesMatches = callstackAddressesRegex.Matches(valueString);

                                            foreach (Match addressMatch in addressesMatches)
                                            {
                                                UInt32 address = Convert.ToUInt32(addressMatch.Value, 16);
                                                callstack.m_functions.Add(GetSymbolNameFromAddress(address));
                                            }

                                            callstack.m_functions.Reverse();

                                            callstacks.Add(callstack);
                                        }
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (version > 1)
                    {
                        eventReader.ReadEvents(m_logDataStream);
                    }

                    UInt32 magic = m_logDataStream.ReadUInt32();

                    if (magic != 0xdeadbeef)
                    {
                        throw new Exception("Frame Record is corrupt");
                    }

                    for (int si = 0, sc = ivSinks.Length; si != sc; ++si)
                    {
                        ivSinks[si].OnFrameRecord(values);
                    }

                    FrameRecord fr = new FrameRecord(m_logData.FrameRecords.Count, frameTimeInS, screenshotImage, m_logData.CreateNewFrameRecordValues(values), userMarkers, callstacks);
                    m_logData.AddFrameRecord(fr, newmds);
                    m_logDataStream.FlushWriteStream();

                    newmds.Clear();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            foreach (var resolver in m_symbolResolvers)
            {
                resolver.Dispose();
            }

            m_symbolResolvers.Clear();

            m_logDataStream.CloseWriteStream();
        }