/**
* Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
*/
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Diagnostics;
namespace MemoryProfiler2
{
/// The lower 2 bits of a pointer are piggy-bagged to store what kind of data follows it. This enum lists the possible types.
public enum EProfilingPayloadType
{
TYPE_Malloc = 0,
TYPE_Free = 1,
TYPE_Realloc = 2,
TYPE_Other = 3,
// Don't add more than 4 values - we only have 2 bits to store this.
}
///
/// The the case of TYPE_Other, this enum determines the subtype of the token.
/// Mirrored in FMallocProfiler.h
///
public enum EProfilingPayloadSubType
{
// Core marker types
/// Marker used to determine when malloc profiler stream has ended.
SUBTYPE_EndOfStreamMarker = 0,
/// Marker used to determine when we need to read data from the next file.
SUBTYPE_EndOfFileMarker = 1,
/// Marker used to determine when a snapshot has been added.
SUBTYPE_SnapshotMarker = 2,
/// Marker used to determine when a new frame has started.
SUBTYPE_FrameTimeMarker = 3,
/// Not used. Only for backward compatibility. Use a new snapshot marker instead.
SUBTYPE_TextMarker = 4,
// Marker types for periodic non-GMalloc memory status updates. Only for backward compatibility, replaced with SUBTYPE_MemoryAllocationStats
/// Marker used to store the total amount of memory used by the game.
SUBTYPE_TotalUsed = 5,
/// Marker used to store the total amount of memory allocated from the OS.
SUBTYPE_TotalAllocated = 6,
/// Marker used to store the allocated in use by the application virtual memory.
SUBTYPE_CPUUsed = 7,
/// Marker used to store the allocated from the OS/allocator, but not used by the application.
SUBTYPE_CPUSlack = 8,
/// Marker used to store the alignment waste from a pooled allocator plus book keeping overhead.
SUBTYPE_CPUWaste = 9,
/// Marker used to store the allocated in use by the application physical memory.
SUBTYPE_GPUUsed = 10,
/// Marker used to store the allocated from the OS, but not used by the application.
SUBTYPE_GPUSlack = 11,
/// Marker used to store the alignment waste from a pooled allocator plus book keeping overhead.
SUBTYPE_GPUWaste = 12,
/// Marker used to store the overhead of the operating system.
SUBTYPE_OSOverhead = 13,
/// Marker used to store the size of loaded executable, stack, static, and global object size.
SUBTYPE_ImageSize = 14,
/// Version 3
// Marker types for automatic snapshots.
/// Marker used to determine when engine has started the cleaning process before loading a new level.
SUBTYPE_SnapshotMarker_LoadMap_Start = 21,
/// Marker used to determine when a new level has started loading.
SUBTYPE_SnapshotMarker_LoadMap_Mid = 22,
/// Marker used to determine when a new level has been loaded.
SUBTYPE_SnapshotMarker_LoadMap_End = 23,
/// Marker used to determine when garbage collection has started.
SUBTYPE_SnapshotMarker_GC_Start = 24,
/// Marker used to determine when garbage collection has finished.
SUBTYPE_SnapshotMarker_GC_End = 25,
/// Marker used to determine when a new streaming level has been requested to load.
SUBTYPE_SnapshotMarker_LevelStream_Start = 26,
/// Marker used to determine when a previously streamed level has been made visible.
SUBTYPE_SnapshotMarker_LevelStream_End = 27,
/// Marker used to store a generic malloc statistics. @see FMallocProfiler::WriteMemoryAllocationStats
SUBTYPE_MemoryAllocationStats = 31,
/// Start licensee-specific subtypes from here.
SUBTYPE_LicenseeBase = 50,
/// Unknown the subtype of the token.
SUBTYPE_Unknown,
};
public interface IMemoryStats
{
}
/// Struct used to hold memory allocation statistics. Mirrored in MemoryBase.h. This need to be a class because of how ReadMemoryAllocationsStats method works.
public class FMemoryAllocationStatsV3
{
/// The total amount of memory used by the game.
public Int64 TotalUsed;
/// The total amount of memory allocated from the OS.
public Int64 TotalAllocated;
// Virtual memory for Xbox and PC / Main memory for PS3 (tracked in the allocators) Host is not included ??
/// The allocated in use by the application virtual memory.
public Int64 CPUUsed;
/// The allocated from the OS/allocator, but not used by the application.
public Int64 CPUSlack;
/// Alignment waste from a pooled allocator plus book keeping overhead.
public Int64 CPUWaste;
/// The amount of free memory before the first malloc has been done. (PS3 only).
public Int64 CPUAvailable;
// Physical memory for Xbox and PC / Local memory for PS3 (tracked in the allocators)
/// The allocated in use by the application physical memory.
public Int64 GPUUsed;
/// The allocated from the OS, but not used by the application.
public Int64 GPUSlack;
/// Alignment waste from a pooled allocator plus book keeping overhead.
public Int64 GPUWaste;
/// The total amount of memory available for the allocator. (PS3 only)
public Int64 GPUAvailable;
/// Used memory as reported by the operating system. (Xbox360, PS3 only)
public Int64 OSReportedUsed;
/// Free memory as reported by the operating system. (Xbox360, PS3 only)
public Int64 OSReportedFree;
/// The overhead of the operating system. (Xbox360 only)
public Int64 OSOverhead;
/// Size of loaded executable, stack, static, and global object size. (Xbox360, PS3 only)
public Int64 ImageSize;
/// Host memory in use by the application. (PS3 only)
public Int64 HostUsed;
/// Host memory allocated, but not used by the application. (PS3 only)
public Int64 HostSlack;
/// Host memory wasted due to allocations' alignment. (PS3 only)
public Int64 HostWaste;
/// The total amount of host memory that has been allocated. (PS3 only)
public Int64 HostAvailable;
/// Size of allocated memory in the texture pool.
public Int64 AllocatedTextureMemorySize;
/// Size of available memory in the texture pool.
public Int64 AvailableTextureMemorySize;
public void Zero()
{
TotalUsed = 0;
TotalAllocated = 0;
CPUUsed = 0;
CPUSlack = 0;
CPUWaste = 0;
CPUAvailable = 0;
GPUUsed = 0;
GPUSlack = 0;
GPUWaste = 0;
GPUAvailable = 0;
HostUsed = 0;
HostSlack = 0;
HostWaste = 0;
HostAvailable = 0;
OSReportedUsed = 0;
OSReportedFree = 0;
OSOverhead = 0;
ImageSize = 0;
AllocatedTextureMemorySize = 0;
AvailableTextureMemorySize = 0;
}
/// Returns a difference between old and new memory allocation stats.
public static FMemoryAllocationStatsV3 Diff( FMemoryAllocationStatsV3 Old, FMemoryAllocationStatsV3 New )
{
FMemoryAllocationStatsV3 Diff = new FMemoryAllocationStatsV3();
FieldInfo[] FieldInfos = typeof( FMemoryAllocationStatsV3 ).GetFields();
int PropertiesNum = FieldInfos.Length;
for( int FieldIndex = 0; FieldIndex < PropertiesNum; FieldIndex++ )
{
Int64 OldValue = (Int64)FieldInfos[ FieldIndex ].GetValue( Old );
Int64 NewValue = (Int64)FieldInfos[ FieldIndex ].GetValue( New );
FieldInfos[ FieldIndex ].SetValue( Diff, NewValue-OldValue );
}
return Diff;
}
/// Creates a new copy of this class.
public FMemoryAllocationStatsV3 DeepCopy()
{
FMemoryAllocationStatsV3 Copy = ( FMemoryAllocationStatsV3 )MemberwiseClone();
return Copy;
}
/// Converts this memory allocation statistics to its equivalent string representation.
public override string ToString()
{
StringBuilder StrBuilder = new StringBuilder(1024);
/// The total amount of memory used by the game.
StrBuilder.AppendLine( " TotalUsed: " + MainWindow.FormatSizeString2( TotalUsed ) );
/// The total amount of memory allocated from the OS.
StrBuilder.AppendLine( " TotalAllocated: " + MainWindow.FormatSizeString2( TotalAllocated ) );
// Virtual memory for Xbox and PC / Main memory for PS3 (tracked in the allocators) Host is not included ??
/// The allocated in use by the application virtual memory.
StrBuilder.AppendLine( " CPUUsed: " + MainWindow.FormatSizeString2( CPUUsed ) );
/// The allocated from the OS/allocator, but not used by the application.
StrBuilder.AppendLine( " CPUSlack: " + MainWindow.FormatSizeString2( CPUSlack ) );
/// Alignment waste from a pooled allocator plus book keeping overhead.
StrBuilder.AppendLine( " CPUWaste: " + MainWindow.FormatSizeString2( CPUWaste ) );
/// The amount of free memory before the first malloc has been done. (PS3 only).
if( FStreamInfo.GlobalInstance.Platform == EPlatformType.PS3 )
{
StrBuilder.AppendLine( " CPUAvailable: " + MainWindow.FormatSizeString2( CPUAvailable ) );
}
// Physical memory for Xbox and PC / Local memory for PS3 (tracked in the allocators)
/// The allocated in use by the application physical memory.
StrBuilder.AppendLine( " GPUUsed: " + MainWindow.FormatSizeString2( GPUUsed ) );
/// The allocated from the OS, but not used by the application.
StrBuilder.AppendLine( " GPUSlack: " + MainWindow.FormatSizeString2( GPUSlack ) );
/// Alignment waste from a pooled allocator plus book keeping overhead.
StrBuilder.AppendLine( " GPUWaste: " + MainWindow.FormatSizeString2( GPUWaste ) );
/// The total amount of memory available for the allocator. (PS3 only)
StrBuilder.AppendLine( " GPUAvailable: " + MainWindow.FormatSizeString2( GPUAvailable ) );
/// Used memory as reported by the operating system. (Xbox360, PS3 only)
if( FStreamInfo.GlobalInstance.Platform == EPlatformType.PS3 || FStreamInfo.GlobalInstance.Platform == EPlatformType.Xbox360 )
{
StrBuilder.AppendLine( " OSReportedUsed: " + MainWindow.FormatSizeString2( OSReportedUsed ) );
}
/// Free memory as reported by the operating system. (Xbox360, PS3 only)
if( FStreamInfo.GlobalInstance.Platform == EPlatformType.PS3 || FStreamInfo.GlobalInstance.Platform == EPlatformType.Xbox360 )
{
StrBuilder.AppendLine( " OSReportedFree: " + MainWindow.FormatSizeString2( OSReportedFree ) );
}
/// The overhead of the operating system. (Xbox360 only)
if( FStreamInfo.GlobalInstance.Platform == EPlatformType.Xbox360 )
{
StrBuilder.AppendLine( " OSOverhead: " + MainWindow.FormatSizeString2( OSOverhead ) );
}
/// Size of loaded executable, stack, static, and global object size. (Xbox360, PS3 only)
if( FStreamInfo.GlobalInstance.Platform == EPlatformType.PS3 || FStreamInfo.GlobalInstance.Platform == EPlatformType.Xbox360 )
{
StrBuilder.AppendLine( " ImageSize: " + MainWindow.FormatSizeString2( ImageSize ) );
}
if( FStreamInfo.GlobalInstance.Platform == EPlatformType.PS3 )
{
/// Host memory in use by the application. (PS3 only)
StrBuilder.AppendLine( " HostUsed: " + MainWindow.FormatSizeString2( HostUsed ) );
/// Host memory allocated, but not used by the application. (PS3 only)
StrBuilder.AppendLine( " HostSlack: " + MainWindow.FormatSizeString2( HostSlack ) );
/// Host memory wasted due to allocations' alignment. (PS3 only)
StrBuilder.AppendLine( " HostWaste: " + MainWindow.FormatSizeString2( HostWaste ) );
/// The total amount of host memory that has been allocated. (PS3 only)
StrBuilder.AppendLine( " HostAvailable: " + MainWindow.FormatSizeString2( HostAvailable ) );
}
/// Size of allocated memory in the texture pool.
StrBuilder.AppendLine( " AllocatedTextureMemorySize: " + MainWindow.FormatSizeString2( AllocatedTextureMemorySize ) );
/// Size of available memory in the texture pool.
StrBuilder.AppendLine( " AvailableTextureMemorySize: " + MainWindow.FormatSizeString2( AvailableTextureMemorySize ) );
return StrBuilder.ToString();
}
};
///
/// Struct used to hold platform memory stats and allocator stats. Valid only for MemoryProfiler2.FProfileDataHeader.Version >= 4.
/// @see FGenericPlatformMemory::GetStatsForMallocProfiler
/// @see FMalloc::GetAllocatorStats
/// @todo add support for non-generic platform memory stats.
///
public class FMemoryAllocationStatsV4
{
// Names of generic platform memory stats. @see FGenericPlatformMemory::GetStatsForMallocProfiler / GenericPlatformMemory.cpp
/// The amount of actual physical memory, in bytes.
static public string PlatformTotalPhysical = "Total Physical";
/// The amount of virtual memory, in bytes.
static public string PlatformTotalVirtual = "Total Virtual";
/// The size of a page, in bytes.
static public string PlatformPageSize = "Page Size";
/// Approximate physical RAM in GB"; 1 on everything except PC. Used for "course tuning", like FPlatformMisc::NumberOfCores().
static public string PlatformTotalPhysicalGB = "Total Physical GB";
/// The amount of physical memory currently available, in bytes.
static public string PlatformAvailablePhysical = "Available Physical";
/// The amount of virtual memory currently available, in bytes.
static public string PlatformAvailableVirtual = "Available Virtual";
/// The amount of physical memory used by the process, in bytes.
static public string PlatformUsedPhysical = "Used Physical";
/// The peak amount of physical memory used by the process, in bytes.
static public string PlatformPeakUsedPhysical = "Peak Used Physical";
/// Total amount of virtual memory used by the process.
static public string PlatformUsedVirtual = "Used Virtual";
/// The peak amount of virtual memory used by the process.
static public string PlatformPeakUsedVirtual = "Peak Used Virtual";
static public string MemoryProfilingOverhead = "Memory Profiling Overhead";
// Names of malloc binned memory stats. @see FMallocBinned.GetAllocatorStats / MallocBinned.h
static public string BinnedWasteCurrent = "Binned Waste Current";
static public string BinnedUsedCurrent = "Binned Used Current";
static public string BinnedSlackCurrent = "Binned Slack Current";
private Dictionary _Stats;
public FMemoryAllocationStatsV4()
{
_Stats = new Dictionary();
}
public FMemoryAllocationStatsV4( FMemoryAllocationStatsV4 Other )
{
this._Stats = new Dictionary( Other._Stats );
}
public Int64 this[string StatName]
{
get
{
Int64 Value = 0;
_Stats.TryGetValue(StatName, out Value);
return Value;
}
set
{
_Stats[StatName] = value;
}
}
public Int64 NumStats()
{
return _Stats.Count;
}
/// Returns a difference between old and new platform memory stats.
public static FMemoryAllocationStatsV4 Diff( FMemoryAllocationStatsV4 Old, FMemoryAllocationStatsV4 New )
{
FMemoryAllocationStatsV4 Diff = new FMemoryAllocationStatsV4();
var Keys = Old._Stats.Keys;
foreach( string KeyValue in Keys )
{
Int64 OldValue = Old[KeyValue];
Int64 NewValue = New[KeyValue];
Diff[KeyValue] = NewValue - OldValue;
}
return Diff;
}
/// Creates a new copy of this class.
public FMemoryAllocationStatsV4 DeepCopy()
{
FMemoryAllocationStatsV4 Copy = new FMemoryAllocationStatsV4(this);
return Copy;
}
/// Converts this memory allocation statistics to its equivalent string representation.
public override string ToString()
{
StringBuilder StrBuilder = new StringBuilder( 1024 );
foreach( KeyValuePair KeyPairValue in _Stats )
{
StrBuilder.AppendLine( string.Format( " {0}: {1}", KeyPairValue.Key, MainWindow.FormatSizeString2( KeyPairValue.Value ) ) );
}
return StrBuilder.ToString();
}
};
///
/// Variable sized token emitted by capture code. The parsing code ReadNextToken deals with this and updates
/// internal data. The calling code is responsible for only accessing member variables associated with the type.
///
public class FStreamToken//@TODO: Can I turn this back into a struct?
{
// Parsing configuration
/// Mask of pointer field to get a real pointer (the two LSB are type fields, and the top bits may be a pool index.
public static UInt64 PointerMask = 0xFFFFFFFFFFFFFFFCUL;
public const UInt64 TypeMask = 0x3UL;
public static int PoolShift = 64;
/// Whether to decode the script callstacks.
public static bool bDecodeScriptCallstacks;
/// Version of the stream, same as FProfileDataHeader.Version
public static uint Version;
/// Position in the stream.
public ulong StreamIndex = 0;
/// Type of token.
public EProfilingPayloadType Type;
/// Subtype of token if it's of TYPE_Other.
public EProfilingPayloadSubType SubType;
/// Pointer in the case of alloc / free.
public UInt64 Pointer;
/// Old pointer in the case of realloc.
public UInt64 OldPointer;
/// New pointer in the case of realloc.
public UInt64 NewPointer;
/// Index into callstack array.
public Int32 CallStackIndex;
/// Size of allocation in alloc / realloc case.
public Int32 Size;
/// Payload if type is TYPE_Other.
public UInt32 Payload;
/// Payload data if type is TYPE_Other and subtype is SUBTYPE_SnapshotMarker or SUBTYPE_TextMarker. Index into array of unique names.
public int TextIndex;
/// Payload data if type is TYPE_Other and subtype is SUBTYPE_FrameTimeMarker. Current delta time in seconds.
public float DeltaTime;
/// Total time, increased every time DeltaTime has been read.
public float TotalTime = 0.0f;
/// Time between two consecutive snapshot markers.
public float ElapsedTime = 0.0f;
/// Memory pool.
public EMemoryPool Pool;
/// Platform dependent memory metrics.
public List Metrics = new List();
/// A list of indices into the name table, one for each loaded level including persistent level.
public List LoadedLevels = new List();
/// Generic memory allocation stats for V3.
public FMemoryAllocationStatsV3 MemoryAllocationStats3 = new FMemoryAllocationStatsV3();
/// Generic memory allocation stats for V4.
public FMemoryAllocationStatsV4 MemoryAllocationStats4 = new FMemoryAllocationStatsV4();
/// Index into script callstack array.
public int ScriptCallstackIndex;
/// Index into script-object type array.
public int ScriptObjectTypeIndex;
/// Reads a script callstack.
/// Stream to serialize data from
void ReadScriptCallstack( BinaryReader BinaryStream )
{
if( bDecodeScriptCallstacks )
{
ScriptCallstackIndex = BinaryStream.ReadUInt16();
bool bAllocatingScriptObject = ( ScriptCallstackIndex & 0x8000 ) != 0;
ScriptCallstackIndex = ScriptCallstackIndex & 0x7FFF;
if( ScriptCallstackIndex == 0x7FFF )
{
ScriptCallstackIndex = -1;
}
if( bAllocatingScriptObject )
{
int ScriptObjectTypeCompactedName = BinaryStream.ReadInt32();
ScriptObjectTypeIndex = ScriptObjectTypeCompactedName & 0x00FFFFFF;
// Number is always 0.
int ScriptObjectTypeNumber = ( ScriptObjectTypeCompactedName & 0x7FFFFFFF ) >> 24;
}
}
}
/// Reads additional data required for GCM callstacks.
/// Stream to serialize data from
bool ReadGCMData(BinaryReader BinaryStream, ref UInt32 UnsignedSize )
{
// @see FMallocGcmProfiler.h
const UInt32 GCM_MEMORY_PROFILER_ID_BIT = 0x80000000;
bool bHasGCMData = false;
if( ( UnsignedSize & GCM_MEMORY_PROFILER_ID_BIT ) == GCM_MEMORY_PROFILER_ID_BIT )
{
// Lower five bits are EAllocationType, upper three bits are EMemoryPool
byte AllocationType = BinaryStream.ReadByte();
Pool = FMemoryPoolInfo.ConvertToMemoryPoolFlag( ( EMemoryPoolSerialized )( AllocationType & 0xe0 ) );
UnsignedSize &= ~GCM_MEMORY_PROFILER_ID_BIT;
bHasGCMData = true;
}
return bHasGCMData;
}
/// Reads platform dependent memory metrics.
/// Stream to serialize data from
void ReadMetrics(BinaryReader BinaryStream)
{
// Read the metrics
int NumMetrics = BinaryStream.ReadByte();
for (int i = 0; i < NumMetrics; i++)
{
Metrics.Add(BinaryStream.ReadInt64());
}
}
/// Reads names of all loaded levels.
/// Stream to serialize data from
void ReadLoadedLevels( BinaryReader BinaryStream )
{
// Read the currently loaded levels
int NumLevels = BinaryStream.ReadInt16();
for( int LevelIndex = 0; LevelIndex < NumLevels; LevelIndex++ )
{
int LevelNameIndex = BinaryStream.ReadInt32();
LoadedLevels.Add( LevelNameIndex );
}
}
/// Reads generic memory allocations stats.
/// Stream to serialize data from
private void ReadMemoryAllocationsStats( BinaryReader BinaryStream )
{
if( Version >= 4 )
{
// Read Platform Memory and Allocator Stats
// @see FMallocProfiler::WriteMemoryAllocationStats
int StatsNum = BinaryStream.ReadByte();
for( int StatIndex = 0; StatIndex < StatsNum; StatIndex++ )
{
int NameIndex = BinaryStream.ReadInt32();
Int64 StatValue = BinaryStream.ReadInt64();
string StatName = FStreamInfo.GlobalInstance.NameArray[NameIndex];
MemoryAllocationStats4[StatName] = StatValue;
}
}
else
{
int StatsNum = BinaryStream.ReadByte();
FieldInfo[] FieldInfos = MemoryAllocationStats3.GetType().GetFields();
int PropertiesNum = FieldInfos.Length;
Debug.Assert( StatsNum == PropertiesNum );
for( int StatIndex = 0; StatIndex < StatsNum; StatIndex++ )
{
Int64 Value = BinaryStream.ReadInt64();
FieldInfos[StatIndex].SetValue( MemoryAllocationStats3, Value );
}
}
}
/// Updates the token with data read from passed in stream and returns whether we've reached the end.
/// Stream to serialize data from
public bool ReadNextToken( BinaryReader BinaryStream )
{
bool bReachedEndOfStream = false;
// Initialize to defaults.
SubType = EProfilingPayloadSubType.SUBTYPE_Unknown;
TextIndex = -1;
// Read the pointer and convert to token type by looking at lowest 2 bits. Pointers are always
// 4 byte aligned so need to clear them again after the conversion.
UInt64 RawPointerData = BinaryStream.ReadUInt64();
Pool = EMemoryPool.MEMPOOL_Main;
Type = (EProfilingPayloadType)(RawPointerData & TypeMask);
Pointer = RawPointerData & PointerMask;
Metrics.Clear();
LoadedLevels.Clear();
MemoryAllocationStats3.Zero();
CallStackIndex = -1;
ScriptCallstackIndex = -1;
ScriptObjectTypeIndex = -1;
NewPointer = 0;
OldPointer = 0;
Size = -1;
Payload = 0;
DeltaTime = -1.0f;
// Serialize based on token type.
switch( Type )
{
// Malloc
case EProfilingPayloadType.TYPE_Malloc:
{
// Get the call stack index.
CallStackIndex = BinaryStream.ReadInt32();
// Get the size of an allocation.
UInt32 UnsignedSize = BinaryStream.ReadUInt32();
// Read GCM data if any.
bool bHasGCMData = ReadGCMData( BinaryStream, ref UnsignedSize );
// If GCM doesn't exist read script callstack.
if( bHasGCMData == false )
{
ReadScriptCallstack( BinaryStream );
}
Size = ( int )UnsignedSize;
break;
}
// Free
case EProfilingPayloadType.TYPE_Free:
{
break;
}
// Realloc
case EProfilingPayloadType.TYPE_Realloc:
{
OldPointer = Pointer;
NewPointer = BinaryStream.ReadUInt64();
CallStackIndex = BinaryStream.ReadInt32();
UInt32 UnsignedSize = BinaryStream.ReadUInt32();
bool bHasGCMData = ReadGCMData( BinaryStream, ref UnsignedSize );
if( bHasGCMData == false )
{
ReadScriptCallstack( BinaryStream );
}
Size = ( int )UnsignedSize;
break;
}
// Other
case EProfilingPayloadType.TYPE_Other:
{
SubType = ( EProfilingPayloadSubType )BinaryStream.ReadInt32();
Payload = BinaryStream.ReadUInt32();
// Read subtype.
switch( SubType )
{
// End of stream!
case EProfilingPayloadSubType.SUBTYPE_EndOfStreamMarker:
{
if( Version >= 4 )
{
ReadMemoryAllocationsStats( BinaryStream );
ReadLoadedLevels( BinaryStream );
}
else
{
ReadMemoryAllocationsStats( BinaryStream );
ReadLoadedLevels( BinaryStream );
ReadMetrics( BinaryStream );
}
bReachedEndOfStream = true;
break;
}
case EProfilingPayloadSubType.SUBTYPE_EndOfFileMarker:
{
break;
}
case EProfilingPayloadSubType.SUBTYPE_SnapshotMarker_LoadMap_Start:
case EProfilingPayloadSubType.SUBTYPE_SnapshotMarker_LoadMap_Mid:
case EProfilingPayloadSubType.SUBTYPE_SnapshotMarker_LoadMap_End:
case EProfilingPayloadSubType.SUBTYPE_SnapshotMarker_GC_Start:
case EProfilingPayloadSubType.SUBTYPE_SnapshotMarker_GC_End:
case EProfilingPayloadSubType.SUBTYPE_SnapshotMarker_LevelStream_Start:
case EProfilingPayloadSubType.SUBTYPE_SnapshotMarker_LevelStream_End:
case EProfilingPayloadSubType.SUBTYPE_SnapshotMarker:
{
TextIndex = ( int )Payload;
if( Version >= 4 )
{
ReadMemoryAllocationsStats( BinaryStream );
ReadLoadedLevels( BinaryStream );
}
else
{
ReadMemoryAllocationsStats( BinaryStream );
ReadLoadedLevels( BinaryStream );
ReadMetrics( BinaryStream );
}
break;
}
case EProfilingPayloadSubType.SUBTYPE_FrameTimeMarker:
{
DeltaTime = BitConverter.ToSingle( System.BitConverter.GetBytes( Payload ), 0 );
TotalTime += DeltaTime;
ElapsedTime += DeltaTime;
break;
}
case EProfilingPayloadSubType.SUBTYPE_TextMarker:
{
TextIndex = ( int )Payload;
break;
}
case EProfilingPayloadSubType.SUBTYPE_MemoryAllocationStats:
{
ReadMemoryAllocationsStats( BinaryStream );
break;
}
case EProfilingPayloadSubType.SUBTYPE_TotalUsed:
case EProfilingPayloadSubType.SUBTYPE_TotalAllocated:
case EProfilingPayloadSubType.SUBTYPE_CPUUsed:
case EProfilingPayloadSubType.SUBTYPE_CPUSlack:
case EProfilingPayloadSubType.SUBTYPE_CPUWaste:
case EProfilingPayloadSubType.SUBTYPE_GPUUsed:
case EProfilingPayloadSubType.SUBTYPE_GPUSlack:
case EProfilingPayloadSubType.SUBTYPE_GPUWaste:
case EProfilingPayloadSubType.SUBTYPE_ImageSize:
case EProfilingPayloadSubType.SUBTYPE_OSOverhead:
{
break;
}
default:
{
throw new InvalidDataException();
}
}
break;
}
}
return !bReachedEndOfStream;
}
}
}