Skip to content

NEW: Added achievable frequency and latency (processing delay) to Input Debugger (ISX-2254) #2142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Mar 13, 2025

Conversation

ekcoh
Copy link
Collaborator

@ekcoh ekcoh commented Feb 19, 2025

Description

Adds achievable sample/event frequency (as well as sensor frequency and global polling frequency) to Input Debugger device window. These are just basic calculations over periods of one second at the moment similar to FPS counter.
Adds input processing delay (average, min, max) to Input Debugger device window.

The diagnostic values are similar to FPS updated once a second to show primarily the average. This is intended to help with diagnosing the behaviour of the system and devices and help spot problems.

Added 11 new test cases to cover the calculators as part of editor test assembly which required modification to accept unsafe code in the test assembly which I believe should be ok to change.

Target frequency shown is based on IOCTL sample frequency query response which I believe is only supported by sensors currently. Polling frequency is as we know global at the moment, but showing it since it relates to devices with polling backends which we currently cannot determine from the system. If both of these could be capability queried in the future we can make a better message here.

Screenshot 2025-02-20 at 10 57 35

Testing status & QA

Tested manually with mouse, keyboard and gamepad on macOS during development.
Added unit tests to verify that calculations are working as expected.

Overall Product Risks

Very small. Has no impact on production or player code.

  • Complexity: 0
  • Halo Effect: 0

Comments to reviewers

If possible to cover sensors in review/QA it would be great.

Note that both label fields have tooltip that also needs review.

Checklist

Before review:

  • Changelog entry added.
    • Explains the change in Changed, Fixed, Added sections.
    • For API change contains an example snippet and/or migration example.
    • JIRA ticket linked, example (case %%). If it is a private issue, just add the case ID without a link.
    • Jira port for the next release set as "Resolved".
  • Tests added/changed, if applicable.
    • Functional tests: 11 new test cases added to InputLatencyCalculatorTests and SampleFrequencyCalculatorTests.
    • Performance tests.
    • Integration tests.
  • Docs for new/changed API's.
    • Xmldoc cross references are set correctly.
    • Added explanation how the API works.
    • Usage code examples added.
    • The manual is updated, if needed.

During merge:

  • Commit message for squash-merge is prefixed with one of the list:
    • NEW: ___.
    • FIX: ___.
    • DOCS: ___.
    • CHANGE: ___.
    • RELEASE: 1.1.0-preview.3.

After merge:

  • Create forward/backward port if needed. If you are blocked from creating a forward port now please add a task to ISX-1444.

@ekcoh ekcoh changed the title ADD: Added achievable frequency and latency (processing delay) to Input Debugger (ISX-2254) ISX-2254 NEW: Added achievable frequency and latency (processing delay) to Input Debugger Feb 19, 2025
@ekcoh ekcoh changed the title ISX-2254 NEW: Added achievable frequency and latency (processing delay) to Input Debugger NEW: Added achievable frequency and latency (processing delay) to Input Debugger (ISX-2254) Feb 19, 2025
Copy link
Collaborator

@ritamerkl ritamerkl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a great to have, thanks for adding this!
I only did a quick run through but it looks good from my POV. I need to take another closer look and try it myself.

private double m_LastUpdateTime;
private int m_SampleCount;

public SampleFrequencyCalculator(float targetFrequency, double realtimeSinceStartup)
Copy link
Collaborator Author

@ekcoh ekcoh Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Target frequency is currently only a "convient storage" here. Hower I would suggest keeping it inside this type since an evolved implementation will likely use it to compute error compared to target and create a CDF or PDF of it to illustrate the applications or architectures ability to promptly react to stimuli.

@ekcoh ekcoh requested a review from duckets February 21, 2025 15:09
@surfnerd
Copy link
Collaborator

I think this is great step toward transparency of processing of input events. I think it should be made clear that this doesn't measure the latency between the creation of an input event to when it shows up on the screen, but from the creation of the event to when it's processed by the input system.

@ekcoh
Copy link
Collaborator Author

ekcoh commented Feb 25, 2025

I think this is great step toward transparency of processing of input events. I think it should be made clear that this doesn't measure the latency between the creation of an input event to when it shows up on the screen, but from the creation of the event to when it's processed by the input system.

Agreed, that's a much simpler/better way to say what I am trying to say in that tool tip. Also why I renamed the label to "Processing Delay". Will try to improve the tooltip based your description here. Thanks! :)

@surfnerd
Copy link
Collaborator

Perhaps the manual could be updated with the new screenshot, and a little blurb about what value this adds could be helpful as well.

@Pauliusd01
Copy link
Collaborator

Is it expected that I'm seeing processing delay this high when plugging in an android device? Is it because It's a "remotely" connected one?

27 02 2025 - Unity 138
27 02 2025 - Unity 139

@Pauliusd01
Copy link
Collaborator

Also, the duelsense controllers have a really high sample frequency, but that might be due to the them being very noisy?
27 02 2025 - Unity 141

@ekcoh
Copy link
Collaborator Author

ekcoh commented Feb 27, 2025

Is it expected that I'm seeing processing delay this high when plugging in an android device? Is it because It's a "remotely" connected one?

27 02 2025 - Unity 138 27 02 2025 - Unity 139

You probably found another issue with remote devices having some unusable timestamps. This is probably a root of other bad things to happen. Great find. Did you use Unity remote to get this happening?

I decided to cap the "age" at 1000.0 ms and this is what you see. However this is only based on current time - event timestamp. If event timestamp comes from another clock (remote) device, this doesn't make sense, so it probably means remote devices are not re-timestamped when coming in to the host or the remote protocol do not allow sending the remote device time to allow computing the true latency (including network latency). I think its unrelated to the PR, but we might to either filter remote ones out for now until we have figured that part out or do something similar.... I didn't try remote when doing this.

@Pauliusd01
Copy link
Collaborator

Pauliusd01 commented Feb 27, 2025

Did you use Unity remote to get this happening?

The steps to repro are: Connect an android device and build with the development build type -> In the Input Debugger click on the Remote Devices dropdown and pick your android device -> in the android devices list double click any device -> Processing Delay is always above 1k ms

@ekcoh
Copy link
Collaborator Author

ekcoh commented Feb 27, 2025

Also, the duelsense controllers have a really high sample frequency, but that might be due to the them being very noisy?

Not really, on Windows which was the platform you tested on, DualSense is processed over HID. The current HID implementation do not have any rate-adoption (apart from max read requests in flight I believe) so it will run as fast as the underlying HID driver allows it to do. It's a good observation since this shows processing differences in platform-dependent code that could be up for discussion. However, you are correct that the noise is part of it as well since the noise will allow events/samples to be forwarded since the state "changes". If there was no noise or if signal was pre filtered it would reduce the frequency while the device is idle.

@ekcoh
Copy link
Collaborator Author

ekcoh commented Feb 27, 2025

E.g. on macOS where I am currently working with another DualSense bug, the achieved frequency is around 65 Hz. So 1/8 compared to Win at the moment.

Copy link
Collaborator

@Pauliusd01 Pauliusd01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked debugger window for these devices: touch, keyboard, mouse, PS and Xbox controllers and commonly used android sensors.

@ekcoh
Copy link
Collaborator Author

ekcoh commented Feb 27, 2025

Thanks for the rigorous testing of this debug feature @Pauliusd01

Copy link
Collaborator

@ritamerkl ritamerkl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving to unblock this, will add more thoughts next week !

@ritamerkl
Copy link
Collaborator

I tested the newly added Input Debugger features myself now, and think it is priceless. The only wish I would have is to name target/ Polling Frequency with a bit more clarity or adding an explanation with a small text underneath, or a hover textbox? For me the meaning wasn't clear initially (your live demo on friday was very helpful) - also for the restrictions eg when n/a shows up and what this means.

@ekcoh
Copy link
Collaborator Author

ekcoh commented Mar 4, 2025

I tested the newly added Input Debugger features myself now, and think it is priceless. The only wish I would have is to name target/ Polling Frequency with a bit more clarity or adding an explanation with a small text underneath, or a hover textbox? For me the meaning wasn't clear initially (your live demo on friday was very helpful) - also for the restrictions eg when n/a shows up and what this means.

I agree, the UI layout isn't very helpful, maybe I should try revisit the IMGUI design here to at least make it a bit better (I think the debugger window is overpopulated to begin with, contains a mix of static and dynamic data and should likely be split into multiple windows and/or perspectives).

Regarding the N/A and Target polling rate I would propose the following:

  • Add a new IOCTL command allowing to query whether a device is subject for polling or not. If it's not, there is no point in showing Polling Frequency. This would be trivial if done on module level and could even be a flag. Will investigate.
  • Only show target if the device responds that it has a device-specific target frequency. This will only show something for sensors currently. In the future I hope all devices can be device-specific.

Taking both above into account maybe we should do this before landing this:

  • Dynamically change "Sampling Frequency" label into "Sample Frequency" if it's a polling device and "Event Frequency" if it's not a polling device. Only for Sampling Frequency would we show a "Target" and the target could mean device-specific target or global polling frequency setting dependencies on device. Then the info is more contextual.

What do you think?

Adding the IOCTL could be done on this branch in managed and separately in native. It just needs a good fallback when we cannot tell. When we cannot tell, maybe we should just hide Target since it doesn't add any info anyways.

@ritamerkl
Copy link
Collaborator

I tested the newly added Input Debugger features myself now, and think it is priceless. The only wish I would have is to name target/ Polling Frequency with a bit more clarity or adding an explanation with a small text underneath, or a hover textbox? For me the meaning wasn't clear initially (your live demo on friday was very helpful) - also for the restrictions eg when n/a shows up and what this means.

I agree, the UI layout isn't very helpful, maybe I should try revisit the IMGUI design here to at least make it a bit better (I think the debugger window is overpopulated to begin with, contains a mix of static and dynamic data and should likely be split into multiple windows and/or perspectives).

Regarding the N/A and Target polling rate I would propose the following:

  • Add a new IOCTL command allowing to query whether a device is subject for polling or not. If it's not, there is no point in showing Polling Frequency. This would be trivial if done on module level and could even be a flag. Will investigate.
  • Only show target if the device responds that it has a device-specific target frequency. This will only show something for sensors currently. In the future I hope all devices can be device-specific.

Taking both above into account maybe we should do this before landing this:

  • Dynamically change "Sampling Frequency" label into "Sample Frequency" if it's a polling device and "Event Frequency" if it's not a polling device. Only for Sampling Frequency would we show a "Target" and the target could mean device-specific target or global polling frequency setting dependencies on device. Then the info is more contextual.

What do you think?

Adding the IOCTL could be done on this branch in managed and separately in native. It just needs a good fallback when we cannot tell. When we cannot tell, maybe we should just hide Target since it doesn't add any info anyways.

Sounds good to me!

Copy link
Contributor

@chrstphrsxtn chrstphrsxtn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing on behalf of docs. Approving so as not to block, but left some suggestions which should be applied before merging.

@@ -42,7 +42,11 @@ In the Input Debugger window, navigate to the __Devices__ list and double-click

![Device in Input Debugger](Images/DeviceInDebugger.png)

The top of the Device window displays general information about the specific Device, such as name, manufacturer, and serial number.
The top of the Device window displays general information about the specific Device, such as name, manufacturer, associated layout, device flags, device ID and serial number. In addition, this section also display the current __sample frequency__ and __processing delay__ of the deivce.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The top of the Device window displays general information about the specific Device, such as name, manufacturer, associated layout, device flags, device ID and serial number. In addition, this section also display the current __sample frequency__ and __processing delay__ of the deivce.
The top of the Device window displays general information about the specific Device, such as name, manufacturer, associated layout, device flags, device ID and serial number. This section also displays the current __sample frequency__ and __processing delay__ of the device.


__Sample frequency__ indicates the current frequency of samples or events the Input System is currently processing at given in Hertz (Hz). For devices receiving events this reflects the current flow of events received by the system, and for device receiving periodic readings this reflects the achievable sample rate of the system. The latter may be compared to the globally configured target sampling frequency, while achievable event frequency is uncorrelated to the sample polling frequency setting.

__Processing delay__ indicates the average, minimum and maximum latency contribution from creating an input event or reading until the Input System has processed the same input event. Note that this excludes any additional input delay caused by OS, drivers or device communication. Also note that this excludes any additional output latency that may be caused by additional processing, rendering, GPU swap-chains or display refresh rate.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
__Processing delay__ indicates the average, minimum and maximum latency contribution from creating an input event or reading until the Input System has processed the same input event. Note that this excludes any additional input delay caused by OS, drivers or device communication. Also note that this excludes any additional output latency that may be caused by additional processing, rendering, GPU swap-chains or display refresh rate.
__Processing delay__ indicates the average, minimum, and maximum time delay from when an input event or reading is created until the Input System has processed it. Note that this excludes any additional input delay caused by OS, drivers, or device communication. Also note that this excludes any additional output latency that may be caused by additional processing, rendering, GPU swap-chains, or display refresh rate.

EditorGUILayout.LabelField(new GUIContent("Sample Frequency", sampleFrequencyTooltip), new GUIContent(m_DeviceFrequencyString), EditorStyles.label);
const string processingDelayTooltip =
"Displays the average, minimum and maximum observed input processing delay. This shows the time from " +
"when an input event is first created within Unity until its processed by the Input System. " +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"when an input event is first created within Unity until its processed by the Input System. " +
"when an input event is first created within Unity until it's processed by the Input System. " +

ekcoh and others added 2 commits March 13, 2025 13:12
Improved documentation

Co-authored-by: chrstphrsxtn <74899224+chrstphrsxtn@users.noreply.github.com>
…utDeviceDebuggerWindow.cs

Co-authored-by: chrstphrsxtn <74899224+chrstphrsxtn@users.noreply.github.com>
@ekcoh ekcoh merged commit ca0d36f into develop Mar 13, 2025
107 of 110 checks passed
@ekcoh ekcoh deleted the isx-2254-frequency-and-latency-in-input-debugger branch March 13, 2025 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants