-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Improve rendering performance by reducing at least one frame rendering delay. #16896
base: master
Are you sure you want to change the base?
Improve rendering performance by reducing at least one frame rendering delay. #16896
Conversation
Before this commit: UI -> render -> UI -> render (then it rendered) After this commit: UI -> render (then it rendered) Yes, It reduced rendering delay at least one frame.
c5607d0
to
26b2a62
Compare
You can test this PR using the following package version. |
It actually works (or supposed to work) in the following way:
On the render frame the following happens (or supposed to happen):
Your PR skips the UI thread step 3, which removes any backpressure, so way more layout/render passes can be triggered by input events: (note that there are way more layout passes than 3 per frame, it's snown like this for readability sake). Since you are doing the layout pass as soon as you have changes, the perceived input delay would indeed be lower, however it comes at the cost of doing way more layout/render passes that can have various consequences for more complex layouts:
Another concern is that WPF does the same what we currently do - it doesn't send try to schedule the next render pass until it gets a completion callback from the render thread - https://github.com/dotnet/wpf/blob/a37f6effb9304cd5479dc58427e13e3645f71c88/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/MediaContext.cs#L561-L568 |
Another problem would be various animations like indeterminate ProgressBar, that would be ticking synchronized with composition commit rate. Since animations are processed as a part of the render/layout pass, the dispatcher might not be able to process jobs with Input priority and user input in general. |
@kekekeks Thank you for the two diagrams you drew! The logic, which was previously assembled from various fragments while reading the code, has now become clear and comprehensive. |
What does the pull request do?
After several hours testing, we found that the Avalonia app renders with a delay after the input event. Comparing to all the same code in WPF, the delay is very noticeable.
Please see the picture above:
PointerMove
event.The first one is the Avalonia app before this PR. The sencond one is the Avalonia app after this PR. The third one is the WPF app. We can see that:
What is the current behavior?
Before this PR, when a pointer event is triggered:
DwmRenderTimerLoop
).DwmRenderTimerLoop
) is ticked and all the rendering is done here.As a result, after a pointer event, the rendering is done at the second frame. This is the reason why we see the rendering delay.
What is the updated/expected behavior with this PR?
After this PR, when a pointer event is triggered:
After a pointer event, the rendering is done at the first frame. As a result, the rendering delay is reduced at least one frame. (16ms on a 60fps screen)
How was the solution implemented (if it's not obvious)?
I can't figure out the best solution to fix this issue. So I want to discuss it with you.
Solution 1 (this PR):
Solution 2:
Solution 3:
Checklist
Breaking changes
If someone create the
MediaContext
with reflection, it will fail because the constructor is changed.Obsoletions / Deprecations
Fixed issues