Skip to content

Commit 6884b43

Browse files
authored
[2.8.1] perf pass (#10643)
* Remove alloc * Return early for IndexFinger * Cache .characteristics calls, which can be expensive * Return early if interaction isn't configured * Formatting * Don't call GetDevicesWithCharacteristics every frame * Use SetPositionAndRotation * Don't update ObjectManipulator twice per frame... * Cache all the InputSystem calls * Disable the line data provider if the pointer isn't active * idk sphere pointer attempt * Cache some stuff in hot loops * Rewrite ObjectManipulator to no longer use a dictionary * Fix ordering of parameters for "expected" and "actual" * Update MixedRealityServiceRegistry.cs * Change ObjectManipulator to use a list * Change back to CoreServices.InputSystem * Update FocusProvider.cs * Add some missing cases and change to else if * Convert some foreach in hot loops to a "cached end condition for loop" * Squash for loops into TryGetPointerDataWithId * Add clearer comment on why we remove only when null * Revert "Disable the line data provider if the pointer isn't active" This reverts commit 5b74c6b. * Rename lineBase to lineDataProvider * Add ProfileAnalyzer package
1 parent 1cee188 commit 6884b43

File tree

18 files changed

+364
-264
lines changed

18 files changed

+364
-264
lines changed

Assets/MRTK/Core/Providers/Hands/HandPoseUtils.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ public static bool IsThumbGrabbing(Handedness hand)
105105
public static float IndexFingerCurl(Handedness handedness)
106106
{
107107
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.Wrist, handedness, out var wristPose) &&
108-
HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexTip, handedness, out var fingerTipPose) &&
109-
HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexKnuckle, handedness, out var fingerKnucklePose))
108+
HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexTip, handedness, out var fingerTipPose) &&
109+
HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexKnuckle, handedness, out var fingerKnucklePose))
110110
{
111111

112112
return CalculateCurl(wristPose.Position, fingerKnucklePose.Position, fingerTipPose.Position);
@@ -122,8 +122,8 @@ public static float IndexFingerCurl(Handedness handedness)
122122
public static float MiddleFingerCurl(Handedness handedness)
123123
{
124124
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.Wrist, handedness, out var wristPose) &&
125-
HandJointUtils.TryGetJointPose(TrackedHandJoint.MiddleTip, handedness, out var fingerTipPose) &&
126-
HandJointUtils.TryGetJointPose(TrackedHandJoint.MiddleKnuckle, handedness, out var fingerKnucklePose))
125+
HandJointUtils.TryGetJointPose(TrackedHandJoint.MiddleTip, handedness, out var fingerTipPose) &&
126+
HandJointUtils.TryGetJointPose(TrackedHandJoint.MiddleKnuckle, handedness, out var fingerKnucklePose))
127127
{
128128
return CalculateCurl(wristPose.Position, fingerKnucklePose.Position, fingerTipPose.Position);
129129
}
@@ -138,8 +138,8 @@ public static float MiddleFingerCurl(Handedness handedness)
138138
public static float RingFingerCurl(Handedness handedness)
139139
{
140140
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.Wrist, handedness, out var wristPose) &&
141-
HandJointUtils.TryGetJointPose(TrackedHandJoint.RingTip, handedness, out var fingerTipPose) &&
142-
HandJointUtils.TryGetJointPose(TrackedHandJoint.RingKnuckle, handedness, out var fingerKnucklePose))
141+
HandJointUtils.TryGetJointPose(TrackedHandJoint.RingTip, handedness, out var fingerTipPose) &&
142+
HandJointUtils.TryGetJointPose(TrackedHandJoint.RingKnuckle, handedness, out var fingerKnucklePose))
143143
{
144144
return CalculateCurl(wristPose.Position, fingerKnucklePose.Position, fingerTipPose.Position);
145145
}
@@ -154,8 +154,8 @@ public static float RingFingerCurl(Handedness handedness)
154154
public static float PinkyFingerCurl(Handedness handedness)
155155
{
156156
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.Wrist, handedness, out var wristPose) &&
157-
HandJointUtils.TryGetJointPose(TrackedHandJoint.PinkyTip, handedness, out var fingerTipPose) &&
158-
HandJointUtils.TryGetJointPose(TrackedHandJoint.PinkyKnuckle, handedness, out var fingerKnucklePose))
157+
HandJointUtils.TryGetJointPose(TrackedHandJoint.PinkyTip, handedness, out var fingerTipPose) &&
158+
HandJointUtils.TryGetJointPose(TrackedHandJoint.PinkyKnuckle, handedness, out var fingerKnucklePose))
159159
{
160160
return CalculateCurl(wristPose.Position, fingerKnucklePose.Position, fingerTipPose.Position);
161161
}
@@ -194,7 +194,7 @@ static private float CalculateCurl(Vector3 wristJoint, Vector3 fingerKnuckleJoin
194194

195195
/// <summary>
196196
/// Pinch calculation of the index finger with the thumb based on the distance between the finger tip and the thumb tip.
197-
/// 4 cm (0.04 unity units) is the treshold for fingers being far apart and pinch being read as 0.
197+
/// 4 cm (0.04 unity units) is the threshold for fingers being far apart and pinch being read as 0.
198198
/// </summary>
199199
/// <param name="handedness">Handedness to query joint pose against.</param>
200200
/// <returns> Float ranging from 0 to 1. 0 if the thumb and finger are not pinched together, 1 if thumb finger are pinched together</returns>
@@ -212,4 +212,4 @@ public static float CalculateIndexPinch(Handedness handedness)
212212
return pinchStrength;
213213
}
214214
}
215-
}
215+
}

Assets/MRTK/Core/Services/MixedRealityToolkit.cs

+8
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,14 @@ private void DestroyAllServices()
11191119
{
11201120
UnregisterService<IMixedRealitySpatialAwarenessSystem>();
11211121
}
1122+
else if (typeof(IMixedRealitySceneSystem).IsAssignableFrom(type))
1123+
{
1124+
UnregisterService<IMixedRealitySceneSystem>();
1125+
}
1126+
else if (typeof(IMixedRealityRaycastProvider).IsAssignableFrom(type))
1127+
{
1128+
UnregisterService<IMixedRealityRaycastProvider>();
1129+
}
11221130
else if (typeof(IMixedRealityTeleportSystem).IsAssignableFrom(type))
11231131
{
11241132
UnregisterService<IMixedRealityTeleportSystem>();

Assets/MRTK/Core/Utilities/CameraFOVChecker.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ public static class CameraFOVChecker
1616
// Help to clear caches when new frame runs
1717
private static int inFOVLastCalculatedFrame = -1;
1818
// Map from grabbable => is the grabbable in FOV for this frame. Cleared every frame
19-
private static Dictionary<Tuple<Collider, Camera>, bool> inFOVColliderCache = new Dictionary<Tuple<Collider, Camera>, bool>();
19+
private static Dictionary<ValueTuple<Collider, Camera>, bool> inFOVColliderCache = new Dictionary<ValueTuple<Collider, Camera>, bool>();
2020
// List of corners shared across all sphere pointer query instances --
2121
// used to store list of corners for a bounds. Shared and static
2222
// to avoid allocating memory each frame
2323
private static List<Vector3> inFOVBoundsCornerPoints = new List<Vector3>();
2424

2525
/// <summary>
26-
/// Returns true if a collider's bounds is within the camera FOV.
26+
/// Returns true if a collider's bounds is within the camera FOV.
2727
/// Utilizes a cache to test if this collider has been seen before and returns current frame's calculated result.
2828
/// NOTE: This is a 'loose' FOV check -- it can return true in cases when the collider is actually not in the FOV
2929
/// because it does an axis-aligned check when testing for large colliders. So, if the axis aligned bounds are in the bounds of the camera, it will return true.
@@ -37,7 +37,7 @@ public static bool IsInFOVCached(this Camera cam, Collider myCollider)
3737
return false;
3838
}
3939

40-
Tuple<Collider, Camera> cameraColliderPair = new Tuple<Collider, Camera>(myCollider, cam);
40+
ValueTuple<Collider, Camera> cameraColliderPair = ValueTuple.Create(myCollider, cam);
4141
bool result;
4242
if (inFOVLastCalculatedFrame != Time.frameCount)
4343
{
@@ -95,6 +95,5 @@ public static bool IsInFOVCached(this Camera cam, Collider myCollider)
9595

9696
return result;
9797
}
98-
9998
}
10099
}

Assets/MRTK/Core/Utilities/CoreServices.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -139,35 +139,35 @@ private static void ResetCacheReferenceFromType(Type serviceType)
139139
{
140140
boundarySystem = null;
141141
}
142-
if (typeof(IMixedRealityCameraSystem).IsAssignableFrom(serviceType))
142+
else if (typeof(IMixedRealityCameraSystem).IsAssignableFrom(serviceType))
143143
{
144144
cameraSystem = null;
145145
}
146-
if (typeof(IMixedRealityDiagnosticsSystem).IsAssignableFrom(serviceType))
146+
else if (typeof(IMixedRealityDiagnosticsSystem).IsAssignableFrom(serviceType))
147147
{
148148
diagnosticsSystem = null;
149149
}
150-
if (typeof(IMixedRealityFocusProvider).IsAssignableFrom(serviceType))
150+
else if (typeof(IMixedRealityFocusProvider).IsAssignableFrom(serviceType))
151151
{
152152
focusProvider = null;
153153
}
154-
if (typeof(IMixedRealityInputSystem).IsAssignableFrom(serviceType))
154+
else if (typeof(IMixedRealityInputSystem).IsAssignableFrom(serviceType))
155155
{
156156
inputSystem = null;
157157
}
158-
if (typeof(IMixedRealityRaycastProvider).IsAssignableFrom(serviceType))
158+
else if (typeof(IMixedRealityRaycastProvider).IsAssignableFrom(serviceType))
159159
{
160160
raycastProvider = null;
161161
}
162-
if (typeof(IMixedRealitySceneSystem).IsAssignableFrom(serviceType))
162+
else if (typeof(IMixedRealitySceneSystem).IsAssignableFrom(serviceType))
163163
{
164164
sceneSystem = null;
165165
}
166-
if (typeof(IMixedRealitySpatialAwarenessSystem).IsAssignableFrom(serviceType))
166+
else if (typeof(IMixedRealitySpatialAwarenessSystem).IsAssignableFrom(serviceType))
167167
{
168168
sceneSystem = null;
169169
}
170-
if (typeof(IMixedRealityTeleportSystem).IsAssignableFrom(serviceType))
170+
else if (typeof(IMixedRealityTeleportSystem).IsAssignableFrom(serviceType))
171171
{
172172
teleportSystem = null;
173173
}
@@ -247,4 +247,4 @@ private static T GetService<T>() where T : IMixedRealityService
247247
return service;
248248
}
249249
}
250-
}
250+
}

Assets/MRTK/Core/Utilities/MixedRealityServiceRegistry.cs

+5-7
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,13 @@ public static bool AddService<T>(T serviceInstance, IMixedRealityServiceRegistra
8080
return false;
8181
}
8282

83-
Type interfaceType = typeof(T);
84-
T existingService;
85-
86-
if (TryGetService<T>(out existingService, serviceInstance.Name))
83+
if (TryGetService<T>(out _, serviceInstance.Name))
8784
{
8885
return false;
8986
}
9087

88+
Type interfaceType = typeof(T);
89+
9190
// Ensure we have a place to put our newly registered service.
9291
if (!registry.ContainsKey(interfaceType))
9392
{
@@ -269,8 +268,7 @@ public static bool TryGetService<T>(
269268
{
270269
Type interfaceType = typeof(T);
271270

272-
IMixedRealityService tempService;
273-
if (TryGetServiceInternal(interfaceType, out tempService, out registrar, name))
271+
if (TryGetServiceInternal(interfaceType, out IMixedRealityService tempService, out registrar, name))
274272
{
275273
Debug.Assert(tempService is T, "The service in the registry does not match the expected type.");
276274
serviceInstance = (T)tempService;
@@ -431,4 +429,4 @@ public static IReadOnlyCollection<IMixedRealityService> GetAllServices(IMixedRea
431429
return null;
432430
}
433431
}
434-
}
432+
}

Assets/MRTK/Providers/OpenXR/Scripts/MicrosoftArticulatedHand.cs

+3
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ protected override void UpdatePoseData(MixedRealityInteractionMapping interactio
298298
CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, interactionMapping.MixedRealityInputAction, interactionMapping.PoseData);
299299
}
300300
break;
301+
// IndexFinger is handled in ArticulatedHandDefinition, so we can safely skip this case.
302+
case DeviceInputType.IndexFinger:
303+
break;
301304
default:
302305
base.UpdatePoseData(interactionMapping, inputDevice);
303306
break;

Assets/MRTK/Providers/OpenXR/Scripts/OpenXRDeviceManager.cs

+17-9
Original file line numberDiff line numberDiff line change
@@ -156,23 +156,27 @@ protected override GenericXRSDKController GetOrAddController(InputDevice inputDe
156156
{
157157
using (GetOrAddControllerPerfMarker.Auto())
158158
{
159+
InputDeviceCharacteristics inputDeviceCharacteristics = inputDevice.characteristics;
160+
159161
// If this is a new input device, search if an existing input device has matching characteristics
160162
if (!ActiveControllers.ContainsKey(inputDevice))
161163
{
162164
foreach (InputDevice device in ActiveControllers.Keys)
163165
{
164-
if (((device.characteristics.IsMaskSet(InputDeviceCharacteristics.Controller) && inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.Controller))
165-
|| (device.characteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking) && inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking)))
166-
&& ((device.characteristics.IsMaskSet(InputDeviceCharacteristics.Left) && inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.Left))
167-
|| (device.characteristics.IsMaskSet(InputDeviceCharacteristics.Right) && inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.Right))))
166+
InputDeviceCharacteristics deviceCharacteristics = device.characteristics;
167+
168+
if (((deviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Controller) && inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Controller))
169+
|| (deviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking) && inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking)))
170+
&& ((deviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Left) && inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Left))
171+
|| (deviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Right) && inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Right))))
168172
{
169173
ActiveControllers.Add(inputDevice, ActiveControllers[device]);
170174
break;
171175
}
172176
}
173177
}
174178

175-
if (inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking)
179+
if (inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking)
176180
&& inputDevice.TryGetFeatureValue(CommonUsages.isTracked, out bool isTracked)
177181
&& !isTracked)
178182
{
@@ -194,13 +198,17 @@ protected override void RemoveController(InputDevice inputDevice)
194198
{
195199
using (RemoveControllerPerfMarker.Auto())
196200
{
201+
InputDeviceCharacteristics inputDeviceCharacteristics = inputDevice.characteristics;
202+
197203
foreach (InputDevice device in ActiveControllers.Keys)
198204
{
205+
InputDeviceCharacteristics deviceCharacteristics = device.characteristics;
206+
199207
if (device != inputDevice
200-
&& ((device.characteristics.IsMaskSet(InputDeviceCharacteristics.Controller) && inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.Controller))
201-
|| (device.characteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking) && inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking)))
202-
&& ((device.characteristics.IsMaskSet(InputDeviceCharacteristics.Left) && inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.Left))
203-
|| (device.characteristics.IsMaskSet(InputDeviceCharacteristics.Right) && inputDevice.characteristics.IsMaskSet(InputDeviceCharacteristics.Right))))
208+
&& ((deviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Controller) && inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Controller))
209+
|| (deviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking) && inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.HandTracking)))
210+
&& ((deviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Left) && inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Left))
211+
|| (deviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Right) && inputDeviceCharacteristics.IsMaskSet(InputDeviceCharacteristics.Right))))
204212
{
205213
ActiveControllers.Remove(inputDevice);
206214
// Since an additional device exists, return so a lost source isn't reported

Assets/MRTK/Providers/XRSDK/Controllers/GenericXRSDKController.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public virtual void UpdateController(InputDevice inputDevice)
7373
{
7474
Debug.LogError($"No interaction configuration for {GetType().Name}");
7575
Enabled = false;
76+
return;
7677
}
7778

7879
UpdateSixDofData(inputDevice);
@@ -453,4 +454,4 @@ public bool StartHapticImpulse(float intensity, float durationInSeconds = float.
453454
/// <inheritdoc />
454455
public void StopHapticFeedback() => lastInputDevice.StopHaptics();
455456
}
456-
}
457+
}

Assets/MRTK/Providers/XRSDK/XRSDKDeviceManager.cs

+38-13
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,27 @@ public virtual bool CheckCapability(MixedRealityCapability capability)
7777

7878
private static readonly ProfilerMarker UpdatePerfMarker = new ProfilerMarker("[MRTK] XRSDKDeviceManager.Update");
7979

80+
public override void Enable()
81+
{
82+
base.Enable();
83+
84+
inputDevices.Clear();
85+
foreach (InputDeviceCharacteristics inputDeviceCharacteristics in DesiredInputCharacteristics)
86+
{
87+
InputDevices.GetDevicesWithCharacteristics(inputDeviceCharacteristics, inputDevicesSubset);
88+
foreach (InputDevice device in inputDevicesSubset)
89+
{
90+
if (!inputDevices.Contains(device))
91+
{
92+
inputDevices.Add(device);
93+
}
94+
}
95+
}
96+
97+
InputDevices.deviceConnected += InputDevices_deviceConnected;
98+
InputDevices.deviceDisconnected += InputDevices_deviceDisconnected;
99+
}
100+
80101
/// <inheritdoc/>
81102
public override void Update()
82103
{
@@ -94,19 +115,6 @@ public override void Update()
94115
return;
95116
}
96117

97-
inputDevices.Clear();
98-
foreach (InputDeviceCharacteristics inputDeviceCharacteristics in DesiredInputCharacteristics)
99-
{
100-
InputDevices.GetDevicesWithCharacteristics(inputDeviceCharacteristics, inputDevicesSubset);
101-
foreach (InputDevice device in inputDevicesSubset)
102-
{
103-
if (!inputDevices.Contains(device))
104-
{
105-
inputDevices.Add(device);
106-
}
107-
}
108-
}
109-
110118
foreach (InputDevice device in inputDevices)
111119
{
112120
if (device.isValid)
@@ -137,6 +145,9 @@ public override void Update()
137145
/// <inheritdoc/>
138146
public override void Disable()
139147
{
148+
InputDevices.deviceConnected -= InputDevices_deviceConnected;
149+
InputDevices.deviceDisconnected -= InputDevices_deviceDisconnected;
150+
140151
var controllersCopy = ActiveControllers.ToReadOnlyCollection();
141152
foreach (var controller in controllersCopy)
142153
{
@@ -146,6 +157,20 @@ public override void Disable()
146157
base.Disable();
147158
}
148159

160+
private void InputDevices_deviceConnected(InputDevice obj)
161+
{
162+
bool characteristicsMatch = (obj.characteristics & (InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.HandTracking)) > 0;
163+
if (characteristicsMatch && !inputDevices.Contains(obj))
164+
{
165+
inputDevices.Add(obj);
166+
}
167+
}
168+
169+
private void InputDevices_deviceDisconnected(InputDevice obj)
170+
{
171+
inputDevices.Remove(obj);
172+
}
173+
149174
#region Controller Utilities
150175

151176
private static readonly ProfilerMarker GetOrAddControllerPerfMarker = new ProfilerMarker("[MRTK] XRSDKDeviceManager.GetOrAddController");

0 commit comments

Comments
 (0)