@@ -25,6 +25,14 @@ namespace Microsoft.MixedReality.Profiling
2525 /// </summary>
2626 public class VisualProfiler : MonoBehaviour
2727 {
28+ private static readonly int maxStringLength = 32 ;
29+ private static readonly int maxTargetFrameRate = 120 ;
30+ private static readonly Vector2 defaultWindowRotation = new Vector2 ( 10.0f , 20.0f ) ;
31+ private static readonly Vector3 defaultWindowScale = new Vector3 ( 0.2f , 0.04f , 1.0f ) ;
32+ private static readonly string usedMemoryString = "Used: " ;
33+ private static readonly string peakMemoryString = "Peak: " ;
34+ private static readonly string limitMemoryString = "Limit: " ;
35+
2836 [ Header ( "Profiler Settings" ) ]
2937 [ SerializeField ]
3038 private bool initiallyActive = true ;
@@ -49,12 +57,6 @@ public class VisualProfiler : MonoBehaviour
4957 [ SerializeField , Range ( 0 , 3 ) ]
5058 private int displayedDecimalDigits = 1 ;
5159 [ SerializeField ]
52- private string usedMemoryString = "Used: {0}MB" ;
53- [ SerializeField ]
54- private string peakMemoryString = "Peak: {0}MB" ;
55- [ SerializeField ]
56- private string limitMemoryString = "Limit: {0}MB" ;
57- [ SerializeField ]
5860 private Color baseColor = new Color ( 80 / 256.0f , 80 / 256.0f , 80 / 256.0f , 1.0f ) ;
5961 [ SerializeField ]
6062 private Color targetFrameRateColor = new Color ( 127 / 256.0f , 186 / 256.0f , 0 / 256.0f , 1.0f ) ;
@@ -87,16 +89,14 @@ public class VisualProfiler : MonoBehaviour
8789 private int frameCount ;
8890 private System . Diagnostics . Stopwatch stopwatch = new System . Diagnostics . Stopwatch ( ) ;
8991 private string [ ] frameRateStrings ;
90- private string displayedDecimalFormat ;
92+ private char [ ] stringBuffer = new char [ maxStringLength ] ;
9193
9294 private ulong memoryUsage ;
9395 private ulong peakMemoryUsage ;
9496 private ulong limitMemoryUsage ;
9597
9698 private KeywordRecognizer keywordRecognizer ;
9799
98- private StringBuilder stringBuilder = new StringBuilder ( 32 ) ;
99-
100100 // Rendering resources.
101101 [ SerializeField , HideInInspector ]
102102 private Material defaultMaterial ;
@@ -107,10 +107,6 @@ public class VisualProfiler : MonoBehaviour
107107 private Material textMaterial ;
108108 private Mesh quadMesh ;
109109
110- private static readonly int maxTargetFrameRate = 120 ;
111- private static readonly Vector2 defaultWindowRotation = new Vector2 ( 10.0f , 20.0f ) ;
112- private static readonly Vector3 defaultWindowScale = new Vector3 ( 0.2f , 0.04f , 1.0f ) ;
113-
114110 private void Reset ( )
115111 {
116112 if ( defaultMaterial == null )
@@ -258,7 +254,7 @@ private void LateUpdate()
258254 {
259255 if ( window . activeSelf && WillDisplayedMemoryUsageDiffer ( limitMemoryUsage , limit , displayedDecimalDigits ) )
260256 {
261- MemoryUsageToString ( stringBuilder , displayedDecimalFormat , limitMemoryText , limitMemoryString , limit ) ;
257+ MemoryUsageToString ( stringBuffer , displayedDecimalDigits , limitMemoryText , limitMemoryString , limit ) ;
262258 }
263259
264260 limitMemoryUsage = limit ;
@@ -272,7 +268,7 @@ private void LateUpdate()
272268
273269 if ( window . activeSelf && WillDisplayedMemoryUsageDiffer ( memoryUsage , usage , displayedDecimalDigits ) )
274270 {
275- MemoryUsageToString ( stringBuilder , displayedDecimalFormat , usedMemoryText , usedMemoryString , usage ) ;
271+ MemoryUsageToString ( stringBuffer , displayedDecimalDigits , usedMemoryText , usedMemoryString , usage ) ;
276272 }
277273
278274 memoryUsage = usage ;
@@ -284,7 +280,7 @@ private void LateUpdate()
284280
285281 if ( window . activeSelf && WillDisplayedMemoryUsageDiffer ( peakMemoryUsage , memoryUsage , displayedDecimalDigits ) )
286282 {
287- MemoryUsageToString ( stringBuilder , displayedDecimalFormat , peakMemoryText , peakMemoryString , memoryUsage ) ;
283+ MemoryUsageToString ( stringBuffer , displayedDecimalDigits , peakMemoryText , peakMemoryString , memoryUsage ) ;
288284 }
289285
290286 peakMemoryUsage = memoryUsage ;
@@ -404,8 +400,9 @@ private void BuildWindow()
404400 private void BuildFrameRateStrings ( )
405401 {
406402 frameRateStrings = new string [ maxTargetFrameRate + 1 ] ;
407- displayedDecimalFormat = string . Format ( "{{0:F{0}}}" , displayedDecimalDigits ) ;
403+ string displayedDecimalFormat = string . Format ( "{{0:F{0}}}" , displayedDecimalDigits ) ;
408404
405+ StringBuilder stringBuilder = new StringBuilder ( 32 ) ;
409406 StringBuilder milisecondStringBuilder = new StringBuilder ( 16 ) ;
410407 stringBuilder . Length = 0 ;
411408
@@ -441,9 +438,9 @@ private void OnPhraseRecognized(PhraseRecognizedEventArgs args)
441438 window . SetActive ( true ) ;
442439
443440 // Force refresh of strings.
444- MemoryUsageToString ( stringBuilder , displayedDecimalFormat , limitMemoryText , limitMemoryString , limitMemoryUsage ) ;
445- MemoryUsageToString ( stringBuilder , displayedDecimalFormat , usedMemoryText , usedMemoryString , memoryUsage ) ;
446- MemoryUsageToString ( stringBuilder , displayedDecimalFormat , peakMemoryText , peakMemoryString , peakMemoryUsage ) ;
441+ MemoryUsageToString ( stringBuffer , displayedDecimalDigits , limitMemoryText , limitMemoryString , limitMemoryUsage ) ;
442+ MemoryUsageToString ( stringBuffer , displayedDecimalDigits , usedMemoryText , usedMemoryString , memoryUsage ) ;
443+ MemoryUsageToString ( stringBuffer , displayedDecimalDigits , peakMemoryText , peakMemoryString , peakMemoryUsage ) ;
447444 }
448445 }
449446 }
@@ -511,31 +508,47 @@ private static void OptimizeRenderer(Renderer renderer)
511508 renderer . motionVectorGenerationMode = MotionVectorGenerationMode . ForceNoMotion ;
512509 renderer . lightProbeUsage = UnityEngine . Rendering . LightProbeUsage . Off ;
513510 renderer . reflectionProbeUsage = UnityEngine . Rendering . ReflectionProbeUsage . Off ;
514- #if UNITY_2017_2_OR_NEWER
515511 renderer . allowOcclusionWhenDynamic = false ;
516- #endif
517512 }
518513
519- private static void MemoryUsageToString ( StringBuilder stringBuilder , string displayedDecimalFormat , TextMesh textMesh , string memoryString , ulong memoryUsage )
514+ private static void MemoryUsageToString ( char [ ] stringBuffer , int displayedDecimalDigits , TextMesh textMesh , string prefixString , ulong memoryUsage )
520515 {
521- stringBuilder . Length = 0 ;
522- // Note, this can trigger an allocation and can be called each frame. But, with default settings this function should only fire with memory deltas of +-1KB.
523- string megabytes = stringBuilder . AppendFormat ( displayedDecimalFormat , ConvertBytesToMegabytes ( memoryUsage ) ) . ToString ( ) ;
524- stringBuilder . Length = 0 ;
525- textMesh . text = stringBuilder . AppendFormat ( memoryString , megabytes ) . ToString ( ) ;
516+ float memoryUsageMB = ConvertBytesToMegabytes ( memoryUsage ) ;
517+ int memoryUsageIntegerDigits = ( int ) memoryUsageMB ;
518+ int memoryUsageFractionalDigits = ( int ) ( ( memoryUsageMB - memoryUsageIntegerDigits ) * Mathf . Pow ( 10.0f , displayedDecimalDigits ) ) ;
519+ int bufferIndex = 0 ;
520+
521+ for ( int i = 0 ; i < prefixString . Length ; ++ i , ++ bufferIndex )
522+ {
523+ stringBuffer [ bufferIndex ] = prefixString [ i ] ;
524+ }
525+
526+ for ( ; memoryUsageIntegerDigits != 0 ; memoryUsageIntegerDigits /= 10 , ++ bufferIndex )
527+ {
528+ stringBuffer [ bufferIndex ] = ( char ) ( ( char ) ( memoryUsageIntegerDigits % 10 ) + '0' ) ;
529+ }
530+
531+ if ( memoryUsageFractionalDigits != 0 )
532+ {
533+ stringBuffer [ bufferIndex ++ ] = '.' ;
534+
535+ for ( ; memoryUsageFractionalDigits != 0 ; memoryUsageFractionalDigits /= 10 , ++ bufferIndex )
536+ {
537+ stringBuffer [ bufferIndex ] = ( char ) ( ( char ) ( memoryUsageFractionalDigits % 10 ) + '0' ) ;
538+ }
539+ }
540+
541+ stringBuffer [ bufferIndex ++ ] = 'M' ;
542+ stringBuffer [ bufferIndex ++ ] = 'B' ;
543+ textMesh . text = new string ( stringBuffer , 0 , bufferIndex ) ;
526544 }
527545
528546 private static float AppFrameRate
529547 {
530548 get
531549 {
532- float refreshRate ;
533- #if UNITY_2017_2_OR_NEWER
534- refreshRate = UnityEngine . XR . XRDevice . refreshRate ;
535- #else
536- refreshRate = UnityEngine . VR . XRDevice . refreshRate ;
537- #endif
538550 // If the current XR SDK does not report refresh rate information, assume 60Hz.
551+ float refreshRate = UnityEngine . XR . XRDevice . refreshRate ;
539552 return ( ( int ) refreshRate == 0 ) ? 60.0f : refreshRate ;
540553 }
541554 }
@@ -564,18 +577,13 @@ private static ulong AppMemoryUsageLimit
564577 }
565578 }
566579
567- private static bool WillDisplayedMemoryUsageDiffer ( ulong oldUsage , ulong newUsage , int memoryUsageDecimalDigits )
580+ private static bool WillDisplayedMemoryUsageDiffer ( ulong oldUsage , ulong newUsage , int displayedDecimalDigits )
568581 {
569582 float oldUsageMBs = ConvertBytesToMegabytes ( oldUsage ) ;
570583 float newUsageMBs = ConvertBytesToMegabytes ( newUsage ) ;
584+ float decimalPower = Mathf . Pow ( 10.0f , displayedDecimalDigits ) ;
571585
572- for ( int i = 0 ; i < memoryUsageDecimalDigits ; ++ i )
573- {
574- oldUsageMBs *= 10.0f ;
575- newUsageMBs *= 10.0f ;
576- }
577-
578- return ( int ) oldUsageMBs != ( int ) newUsageMBs ;
586+ return ( int ) ( oldUsageMBs * decimalPower ) != ( int ) ( newUsageMBs * decimalPower ) ;
579587 }
580588
581589 private static ulong ConvertMegabytesToBytes ( int megabytes )
0 commit comments