11// Copyright (c) Microsoft Corporation. All rights reserved.
22// Licensed under the MIT License. See LICENSE in the project root for license information.
33
4- using UnityEngine ;
5- using UnityEngine . Windows . Speech ;
64using System . Text ;
5+ using UnityEngine ;
76using UnityEngine . Profiling ;
7+ using UnityEngine . Windows . Speech ;
88
9- namespace Microsoft . MixedReality . Profiling
9+ #if WINDOWS_UWP
10+ using Windows . System ;
11+ #endif
12+
13+ namespace Microsoft . MixedReality . Toolkit . Diagnostics
1014{
1115 /// <summary>
1216 ///
@@ -15,9 +19,9 @@ namespace Microsoft.MixedReality.Profiling
1519 /// frames are displayed over time to visually find problem areas. Memory is reported
1620 /// as current, peak and max usage in a bar graph.
1721 ///
18- /// USAGE: To use this profiler simply add this script as a component of any gameobject in
19- /// your Unity scene. The profiler is initially enabled (toggle-able via the initiallyActive
20- /// property), but can be toggled via the enabled/disable voice commands keywords.
22+ /// USAGE: To use this profiler simply add this script as a component of any GameObject in
23+ /// your Unity scene. The profiler is initially active and visible (toggle-able via the
24+ /// IsVisible property), but can be toggled via the enabled/disable voice commands keywords.
2125 ///
2226 /// NOTE: For improved rendering performance you can optionally include the
2327 /// "Hidden/Instanced-Colored" shader in your project along with the VisualProfiler.
@@ -33,33 +37,74 @@ public class VisualProfiler : MonoBehaviour
3337 private static readonly int maxStringLength = 32 ;
3438 private static readonly int maxTargetFrameRate = 120 ;
3539 private static readonly int maxFrameTimings = 128 ;
40+ private static readonly int frameRange = 30 ;
3641 private static readonly Vector2 defaultWindowRotation = new Vector2 ( 10.0f , 20.0f ) ;
3742 private static readonly Vector3 defaultWindowScale = new Vector3 ( 0.2f , 0.04f , 1.0f ) ;
3843 private static readonly string usedMemoryString = "Used: " ;
3944 private static readonly string peakMemoryString = "Peak: " ;
4045 private static readonly string limitMemoryString = "Limit: " ;
4146
47+ public Transform WindowParent { get ; set ; } = null ;
48+
4249 [ Header ( "Profiler Settings" ) ]
43- [ SerializeField , Tooltip ( "Should the profiler display automatically or wait for user activation via voice, etc." ) ]
44- private bool initiallyActive = true ;
45- [ SerializeField , Tooltip ( "Voice commands to toggle the profiler on and off." ) ]
46- private string [ ] toggleKeyworlds = new string [ ] { "Profiler" , "Toggle Profiler" , "Show Profiler" , "Hide Profiler" } ;
47- [ SerializeField , Range ( 1 , 60 ) , Tooltip ( "How many frames to display as colored boxes indicating target or missed frames." ) ]
48- private int frameRange = 30 ;
49- [ SerializeField , Range ( 0.0f , 1.0f ) , Tooltip ( "How often to update the displayed frame rate(s)." ) ]
50+ [ SerializeField , Tooltip ( "Is the profiler currently visible." ) ]
51+ private bool isVisible = true ;
52+
53+ public bool IsVisible
54+ {
55+ get { return isVisible ; }
56+ set { isVisible = value ; }
57+ }
58+
59+ [ SerializeField , Tooltip ( "The amount of time, in seconds, to collect frames for frame rate calculation." ) ]
5060 private float frameSampleRate = 0.1f ;
5161
62+ public float FrameSampleRate
63+ {
64+ get { return frameSampleRate ; }
65+ set { frameSampleRate = value ; }
66+ }
67+
5268 [ Header ( "Window Settings" ) ]
5369 [ SerializeField , Tooltip ( "What part of the view port to anchor the window to." ) ]
5470 private TextAnchor windowAnchor = TextAnchor . LowerCenter ;
71+
72+ public TextAnchor WindowAnchor
73+ {
74+ get { return windowAnchor ; }
75+ set { windowAnchor = value ; }
76+ }
77+
5578 [ SerializeField , Tooltip ( "The offset from the view port center applied based on the window anchor selection." ) ]
5679 private Vector2 windowOffset = new Vector2 ( 0.1f , 0.1f ) ;
80+
81+ public Vector2 WindowOffset
82+ {
83+ get { return windowOffset ; }
84+ set { windowOffset = value ; }
85+ }
86+
5787 [ SerializeField , Range ( 0.5f , 5.0f ) , Tooltip ( "Use to scale the window size up or down, can simulate a zooming effect." ) ]
5888 private float windowScale = 1.0f ;
89+
90+ public float WindowScale
91+ {
92+ get { return windowScale ; }
93+ set { windowScale = Mathf . Clamp ( value , 0.5f , 5.0f ) ; }
94+ }
95+
5996 [ SerializeField , Range ( 0.0f , 100.0f ) , Tooltip ( "How quickly to interpolate the window towards its target position and rotation." ) ]
6097 private float windowFollowSpeed = 5.0f ;
6198
99+ public float WindowFollowSpeed
100+ {
101+ get { return windowFollowSpeed ; }
102+ set { windowFollowSpeed = Mathf . Abs ( value ) ; }
103+ }
104+
62105 [ Header ( "UI Settings" ) ]
106+ [ SerializeField , Tooltip ( "Voice commands to toggle the profiler on and off." ) ]
107+ private string [ ] toggleKeyworlds = new string [ ] { "Profiler" , "Toggle Profiler" , "Show Profiler" , "Hide Profiler" } ;
63108 [ SerializeField , Range ( 0 , 3 ) , Tooltip ( "How many decimal places to display on numeric strings." ) ]
64109 private int displayedDecimalDigits = 1 ;
65110 [ SerializeField , Tooltip ( "The color of the window backplate." ) ]
@@ -88,7 +133,7 @@ public class VisualProfiler : MonoBehaviour
88133 private Quaternion windowVerticalRotation ;
89134 private Quaternion windowVerticalRotationInverse ;
90135
91- private Matrix4x4 [ ] frameInfoMatricies ;
136+ private Matrix4x4 [ ] frameInfoMatrices ;
92137 private Vector4 [ ] frameInfoColors ;
93138 private MaterialPropertyBlock frameInfoPropertyBlock ;
94139 private int colorID ;
@@ -140,7 +185,7 @@ private void Reset()
140185 }
141186 else
142187 {
143- Debug . LogWarning ( "A shader supporting instancing could not be found for the VisualProfiler, falling back to traditional rendering." ) ;
188+ Debug . LogWarning ( "A shader supporting instancing could not be found for the VisualProfiler, falling back to traditional rendering. This may impact performance. " ) ;
144189 }
145190 }
146191
@@ -271,15 +316,15 @@ private void LateUpdate()
271316 if ( defaultInstancedMaterial != null )
272317 {
273318 frameInfoPropertyBlock . SetMatrix ( parentMatrixID , parentLocalToWorldMatrix ) ;
274- Graphics . DrawMeshInstanced ( quadMesh , 0 , defaultInstancedMaterial , frameInfoMatricies , frameInfoMatricies . Length , frameInfoPropertyBlock , UnityEngine . Rendering . ShadowCastingMode . Off , false ) ;
319+ Graphics . DrawMeshInstanced ( quadMesh , 0 , defaultInstancedMaterial , frameInfoMatrices , frameInfoMatrices . Length , frameInfoPropertyBlock , UnityEngine . Rendering . ShadowCastingMode . Off , false ) ;
275320 }
276321 else
277322 {
278323 // If a instanced material is not available, fall back to non-instanced rendering.
279- for ( int i = 0 ; i < frameInfoMatricies . Length ; ++ i )
324+ for ( int i = 0 ; i < frameInfoMatrices . Length ; ++ i )
280325 {
281326 frameInfoPropertyBlock . SetColor ( colorID , frameInfoColors [ i ] ) ;
282- Graphics . DrawMesh ( quadMesh , parentLocalToWorldMatrix * frameInfoMatricies [ i ] , defaultMaterial , 0 , null , 0 , frameInfoPropertyBlock , false , false , false ) ;
327+ Graphics . DrawMesh ( quadMesh , parentLocalToWorldMatrix * frameInfoMatrices [ i ] , defaultMaterial , 0 , null , 0 , frameInfoPropertyBlock , false , false , false ) ;
283328 }
284329 }
285330 }
@@ -322,6 +367,8 @@ private void LateUpdate()
322367
323368 peakMemoryUsage = memoryUsage ;
324369 }
370+
371+ window . SetActive ( isVisible ) ;
325372 }
326373
327374 private Vector3 CalculateWindowPosition ( Transform cameraTransform )
@@ -374,6 +421,7 @@ private void BuildWindow()
374421 // Build the window root.
375422 {
376423 window = CreateQuad ( "VisualProfiler" , null ) ;
424+ window . transform . parent = WindowParent ;
377425 InitializeRenderer ( window , backgroundMaterial , colorID , baseColor ) ;
378426 window . transform . localScale = defaultWindowScale ;
379427 windowHorizontalRotation = Quaternion . AngleAxis ( defaultWindowRotation . y , Vector3 . right ) ;
@@ -388,14 +436,14 @@ private void BuildWindow()
388436 gpuFrameRateText = CreateText ( "GPUFrameRateText" , new Vector3 ( 0.495f , 0.5f , 0.0f ) , window . transform , TextAnchor . UpperRight , textMaterial , Color . white , string . Empty ) ;
389437 gpuFrameRateText . gameObject . SetActive ( false ) ;
390438
391- frameInfoMatricies = new Matrix4x4 [ frameRange ] ;
439+ frameInfoMatrices = new Matrix4x4 [ frameRange ] ;
392440 frameInfoColors = new Vector4 [ frameRange ] ;
393441 Vector3 scale = new Vector3 ( 1.0f / frameRange , 0.2f , 1.0f ) ;
394442 Vector3 position = new Vector3 ( 0.5f - ( scale . x * 0.5f ) , 0.15f , 0.0f ) ;
395443
396444 for ( int i = 0 ; i < frameRange ; ++ i )
397445 {
398- frameInfoMatricies [ i ] = Matrix4x4 . TRS ( position , Quaternion . identity , new Vector3 ( scale . x * 0.8f , scale . y , scale . z ) ) ;
446+ frameInfoMatrices [ i ] = Matrix4x4 . TRS ( position , Quaternion . identity , new Vector3 ( scale . x * 0.8f , scale . y , scale . z ) ) ;
399447 position . x -= scale . x ;
400448 frameInfoColors [ i ] = targetFrameRateColor ;
401449 }
@@ -433,7 +481,7 @@ private void BuildWindow()
433481 }
434482 }
435483
436- window . SetActive ( initiallyActive ) ;
484+ window . SetActive ( isVisible ) ;
437485 }
438486
439487 private void BuildFrameRateStrings ( )
@@ -555,6 +603,8 @@ private static void OptimizeRenderer(Renderer renderer)
555603
556604 private static void MemoryUsageToString ( char [ ] stringBuffer , int displayedDecimalDigits , TextMesh textMesh , string prefixString , ulong memoryUsage )
557605 {
606+ // Using a custom number to string method to avoid the overhead, and allocations, of built in string.Format/StringBuilder methods.
607+ // We can also make some assumptions since the domain of the input number (memoryUsage) is known.
558608 float memoryUsageMB = ConvertBytesToMegabytes ( memoryUsage ) ;
559609 int memoryUsageIntegerDigits = ( int ) memoryUsageMB ;
560610 int memoryUsageFractionalDigits = ( int ) ( ( memoryUsageMB - memoryUsageIntegerDigits ) * Mathf . Pow ( 10.0f , displayedDecimalDigits ) ) ;
@@ -638,7 +688,7 @@ private static ulong AppMemoryUsage
638688 get
639689 {
640690#if WINDOWS_UWP
641- return Windows . System . MemoryManager . AppMemoryUsage ;
691+ return MemoryManager . AppMemoryUsage ;
642692#else
643693 return ( ulong ) Profiler . GetTotalAllocatedMemoryLong ( ) ;
644694#endif
@@ -650,7 +700,7 @@ private static ulong AppMemoryUsageLimit
650700 get
651701 {
652702#if WINDOWS_UWP
653- return Windows . System . MemoryManager . AppMemoryUsageLimit ;
703+ return MemoryManager . AppMemoryUsageLimit ;
654704#else
655705 return ConvertMegabytesToBytes ( SystemInfo . systemMemorySize ) ;
656706#endif
0 commit comments