123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- #region copyright
- //-------------------------------------------------------
- // Copyright (C) Dmitriy Yukhanov [https://codestage.net]
- //-------------------------------------------------------
- #endregion
- #if DEVELOPMENT_BUILD || UNITY_EDITOR
- #define ENABLE_GFX_MEMORY
- #endif
- namespace CodeStage.AdvancedFPSCounter.CountersData
- {
- using System.Collections;
- using UnityEngine;
- using UnityEngine.Profiling;
- using Utils;
- /// <summary>
- /// Shows memory usage data.
- /// </summary>
- [System.Serializable]
- public class MemoryCounterData : UpdatableCounterData
- {
- // ----------------------------------------------------------------------------
- // constants
- // ----------------------------------------------------------------------------
- public const long MemoryDivider = 1048576; // 1024^2
- private const string TextStart = "<color=#{0}>";
- private const string LineStartTotal = "MEM TOTAL: ";
- private const string LineStartAllocated = "MEM ALLOC: ";
- private const string LineStartMono = "MEM MONO: ";
- #if ENABLE_GFX_MEMORY
- private const string LineStartGfx = "MEM GFX: ";
- #endif
- private const string LineEnd = " MB";
- private const string TextEnd = "</color>";
- // ----------------------------------------------------------------------------
- // properties exposed to the inspector
- // ----------------------------------------------------------------------------
- #region Precise
- [Tooltip("Allows to output memory usage more precisely thus using a bit more system resources.")]
- [SerializeField]
- private bool precise = true;
- /// <summary>
- /// Allows to output memory usage more precisely thus using a bit more system resources.
- /// </summary>
- public bool Precise
- {
- get { return precise; }
- set
- {
- if (precise == value || !Application.isPlaying) return;
- precise = value;
- if (!enabled) return;
- Refresh();
- }
- }
- #endregion
- #region Total
- [Tooltip("Allows to see private memory amount reserved for application. This memory can’t be used by other applications.")]
- [SerializeField]
- private bool total = true;
- /// <summary>
- /// Allows to see private memory amount reserved for application. This memory can’t be used by other applications.
- /// </summary>
- public bool Total
- {
- get { return total; }
- set
- {
- if (total == value || !Application.isPlaying) return;
- total = value;
- if (!total) LastTotalValue = 0;
- if (!enabled) return;
- Refresh();
- }
- }
- #endregion
- #region Allocated
- [Tooltip("Allows to see amount of memory, currently allocated by application.")]
- [SerializeField]
- private bool allocated = true;
- /// <summary>
- /// Allows to see amount of memory, currently allocated by application.
- /// </summary>
- public bool Allocated
- {
- get { return allocated; }
- set
- {
- if (allocated == value || !Application.isPlaying) return;
- allocated = value;
- if (!allocated) LastAllocatedValue = 0;
- if (!enabled) return;
- Refresh();
- }
- }
- #endregion
- #region MonoUsage
- [Tooltip("Allows to see amount of memory, allocated by managed Mono objects, " +
- "such as UnityEngine.Object and everything derived from it for example.")]
- [SerializeField]
- private bool monoUsage;
- /// <summary>
- /// Allows to see amount of memory, allocated by managed Mono objects,
- /// such as UnityEngine.Object and everything derived from it for example.
- /// </summary>
- public bool MonoUsage
- {
- get { return monoUsage; }
- set
- {
- if (monoUsage == value || !Application.isPlaying) return;
- monoUsage = value;
- if (!monoUsage) LastMonoValue = 0;
- if (!enabled) return;
- Refresh();
- }
- }
- #endregion
- #region GFX
- [Tooltip("Allows to see amount of allocated memory for the graphics driver (dev builds only).")]
- [SerializeField]
- private bool gfx = true;
- /// <summary>
- /// Allows to see amount of allocated memory for the graphics driver.
- /// Requires Unity 2018.1.0 or newer and Development build.
- /// This value is not included into the Total memory counter.
- /// </summary>
- public bool Gfx
- {
- get { return gfx; }
- set
- {
- if (gfx == value || !Application.isPlaying) return;
- gfx = value;
- if (!gfx) LastGfxValue = 0;
- if (!enabled) return;
- Refresh();
- }
- }
- #endregion
- // ----------------------------------------------------------------------------
- // properties only accessible from code
- // ----------------------------------------------------------------------------
- /// <summary>
- /// Last total memory readout.
- /// </summary>
- /// In megabytes if #Precise is false, in bytes otherwise.
- /// @see Total
- public long LastTotalValue { get; private set; }
- /// <summary>
- /// Last allocated memory readout.
- /// </summary>
- /// In megabytes if #Precise is false, in bytes otherwise.
- /// @see Allocated
- public long LastAllocatedValue { get; private set; }
- /// <summary>
- /// Last Mono memory readout.
- /// </summary>
- /// In megabytes if #Precise is false, in bytes otherwise.
- /// @see MonoUsage
- public long LastMonoValue { get; private set; }
- /// <summary>
- /// Last graphics driver memory readout.
- /// </summary>
- /// In megabytes if #Precise is false, in bytes otherwise.
- /// @see Gfx
- public long LastGfxValue { get; private set; }
- // ----------------------------------------------------------------------------
- // constructor
- // ----------------------------------------------------------------------------
- internal MemoryCounterData()
- {
- color = new Color32(234, 238, 101, 255);
- style = FontStyle.Bold;
- }
- // ----------------------------------------------------------------------------
- // internal methods
- // ----------------------------------------------------------------------------
- internal override void UpdateValue(bool force)
- {
- if (!enabled) return;
- if (force)
- {
- if (!inited && (HasData()))
- {
- Activate();
- return;
- }
- if (inited && (!HasData()))
- {
- Deactivate();
- return;
- }
- }
- if (total)
- {
- var value = Profiler.GetTotalReservedMemoryLong();
- long divisionResult = 0;
- bool newValue;
- if (precise)
- {
- newValue = LastTotalValue != value;
- }
- else
- {
- divisionResult = value / MemoryDivider;
- newValue = LastTotalValue != divisionResult;
- }
- if (newValue || force)
- {
- LastTotalValue = precise ? value : divisionResult;
- dirty = true;
- }
- }
- if (allocated)
- {
- var value = Profiler.GetTotalAllocatedMemoryLong();
- long divisionResult = 0;
- bool newValue;
- if (precise)
- {
- newValue = LastAllocatedValue != value;
- }
- else
- {
- divisionResult = value / MemoryDivider;
- newValue = (LastAllocatedValue != divisionResult);
- }
- if (newValue || force)
- {
- LastAllocatedValue = precise ? value : divisionResult;
- dirty = true;
- }
- }
- if (monoUsage)
- {
- var monoMemory = System.GC.GetTotalMemory(false);
- long divisionResult = 0;
- bool newValue;
- if (precise)
- {
- newValue = (LastMonoValue != monoMemory);
- }
- else
- {
- divisionResult = monoMemory / MemoryDivider;
- newValue = (LastMonoValue != divisionResult);
- }
- if (newValue || force)
- {
- LastMonoValue = precise ? monoMemory : divisionResult;
- dirty = true;
- }
- }
- #if ENABLE_GFX_MEMORY
- if (gfx)
- {
- var value = Profiler.GetAllocatedMemoryForGraphicsDriver();
- long divisionResult = 0;
- bool newValue;
- if (precise)
- {
- newValue = LastGfxValue != value;
- }
- else
- {
- divisionResult = value / MemoryDivider;
- newValue = LastGfxValue != divisionResult;
- }
- if (newValue || force)
- {
- LastGfxValue = precise ? value : divisionResult;
- dirty = true;
- }
- }
- #endif
- if (!dirty || main.OperationMode != OperationMode.Normal) return;
- var needNewLine = false;
- text.Length = 0;
- text.Append(colorCached);
- if (total)
- {
- text.Append(LineStartTotal);
- if (precise)
- {
- text.AppendLookup(LastTotalValue / (float)MemoryDivider);
- }
- else
- {
- text.AppendLookup(LastTotalValue);
- }
- text.Append(LineEnd);
- needNewLine = true;
- }
- if (allocated)
- {
- if (needNewLine) text.Append(AFPSCounter.NewLine);
- text.Append(LineStartAllocated);
- if (precise)
- {
- text.AppendLookup(LastAllocatedValue / (float)MemoryDivider);
- }
- else
- {
- text.AppendLookup(LastAllocatedValue);
- }
- text.Append(LineEnd);
- needNewLine = true;
- }
- if (monoUsage)
- {
- if (needNewLine) text.Append(AFPSCounter.NewLine);
- text.Append(LineStartMono);
- if (precise)
- {
- text.AppendLookup(LastMonoValue / (float)MemoryDivider);
- }
- else
- {
- text.AppendLookup(LastMonoValue);
- }
- text.Append(LineEnd);
- #if ENABLE_GFX_MEMORY
- needNewLine = true;
- #endif
- }
- #if ENABLE_GFX_MEMORY
- if (gfx)
- {
- if (needNewLine) text.Append(AFPSCounter.NewLine);
- text.Append(LineStartGfx);
- if (precise)
- {
- text.AppendLookup(LastGfxValue / (float)MemoryDivider);
- }
- else
- {
- text.AppendLookup(LastGfxValue);
- }
- text.Append(LineEnd);
- }
- #endif
- text.Append(TextEnd);
- ApplyTextStyles();
- }
- // ----------------------------------------------------------------------------
- // protected methods
- // ----------------------------------------------------------------------------
- protected override void PerformActivationActions()
- {
- base.PerformActivationActions();
- if (!HasData()) return;
- LastTotalValue = 0;
- LastAllocatedValue = 0;
- LastMonoValue = 0;
- if (main.OperationMode == OperationMode.Normal)
- {
- if (colorCached == null)
- {
- colorCached = string.Format(TextStart, AFPSCounter.Color32ToHex(color));
- }
- text.Append(colorCached);
- if (total)
- {
- if (precise)
- {
- text.Append(LineStartTotal).Append("0.00").Append(LineEnd);
- }
- else
- {
- text.Append(LineStartTotal).Append(0).Append(LineEnd);
- }
- }
- if (allocated)
- {
- if (text.Length > 0) text.Append(AFPSCounter.NewLine);
- if (precise)
- {
- text.Append(LineStartAllocated).Append("0.00").Append(LineEnd);
- }
- else
- {
- text.Append(LineStartAllocated).Append(0).Append(LineEnd);
- }
- }
- if (monoUsage)
- {
- if (text.Length > 0) text.Append(AFPSCounter.NewLine);
- if (precise)
- {
- text.Append(LineStartMono).Append("0.00").Append(LineEnd);
- }
- else
- {
- text.Append(LineStartMono).Append(0).Append(LineEnd);
- }
- }
- #if ENABLE_GFX_MEMORY
- if (gfx)
- {
- if (text.Length > 0) text.Append(AFPSCounter.NewLine);
- if (precise)
- {
- text.Append(LineStartGfx).Append("0.00").Append(LineEnd);
- }
- else
- {
- text.Append(LineStartGfx).Append(0).Append(LineEnd);
- }
- }
- #endif
- text.Append(TextEnd);
- ApplyTextStyles();
- dirty = true;
- }
- }
- protected override void PerformDeActivationActions()
- {
- base.PerformDeActivationActions();
- if (text != null) text.Length = 0;
- main.MakeDrawableLabelDirty(anchor);
- }
- protected override IEnumerator UpdateCounter()
- {
- while (true)
- {
- UpdateValue();
- main.UpdateTexts();
- var previousUpdateTime = Time.unscaledTime;
- while (Time.unscaledTime < previousUpdateTime + updateInterval)
- {
- yield return null;
- }
- }
- }
- protected override bool HasData()
- {
- return total || allocated || monoUsage || gfx;
- }
- protected override void CacheCurrentColor()
- {
- colorCached = string.Format(TextStart, AFPSCounter.Color32ToHex(color));
- }
- }
- }
|