-
Notifications
You must be signed in to change notification settings - Fork 543
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
[mtl] present with transaction, optionally #3627
Conversation
So I rewrote the if image.present_with_transaction {
command_buffer.commit();
command_buffer.wait_until_scheduled();
image.drawable.present();
} else {
command_buffer.present_drawable(&image.drawable);
command_buffer.commit();
} Because the apple docs on presentWithTransaction says that you "commit, waitUntilScheduled, present" to ensure that the transaction is available. This works, in that all frames I get are perfect, but after couple of back-to-back resize events, I get a second long stall which is subpar. I wonder if I'm flooding it with frames somehow. Funny thing, with this setup, my fps counter goes to 120, disabling the feature and its back to 60. |
Though I get "not annoying anymore, even if technically not perfect" solution was to put this at the start of Perhaps winit could do that instead. let NSViewLayerContentsPlacementTopLeft = 11;
if let Some(v) = view {
unsafe { let () = msg_send![v.as_ptr(), setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; }
} |
@scoopr that seems like an interesting solution without any obvious costs. Want to make a PR for it? |
For whatever reason, setting the layerContentsPlacement in winit side didn't work for me, I wonder if it somehow gets reset when the layer is added to the view. There is few downsides I've seen so far.. One is a smaller thing, the resizing from left edge is can result in black bars to the right side etc., but its not like something like vscode handles that all that much better. But a real issue is that the dpi changes (like dragging a window from hires screen to lores) leaves the layer to be completely wrong size. I guess it needs to watch for those notifications and set the backing scale factor. The default scaling behavior handles that fine. |
Just to document my tests,
|
@scoopr I just realized I didn't push the changes to the right branch. The thing that works for me is close to what you describe in #3627 (comment), and it's pushed now. Am I reading this right that the only concern with the change was having a long stall, and this turned out to be a problem with how you handle Also, do you understand why the original code here didn't work as expected? The one with the "scheduled handler", I'd expect it to do the same thing, just more asynchronously. |
Well, if I don't render within the Resized event, then there is no resized frame to display, so the result is perfectly synchronized wrong frame. Not sure why the scheduled way didn't work, perhaps there is some work done after the final user callback when properly waiting for it 🤷 Does metal call those callbacks straight from the NSRunLoop queue? I guess you could post a dispatch_async on the mainloop so it would run the persent just after the callback as opposed in the callback, dunno. I think the layer placement should be done in any case, because that makes the error-behaviour to be the least annoying and works in all cases, just need to take care of the small details so the size is correctly tracked. It would be nice to have the present_with_transaction flow to work as well, maybe by making one of the vsyncing PresentModes use it, or as an additional option. But need to be careful with it so that it wouldn't be a non-obvious perfomance footgun, or document well on the restrictions it might impose. |
@scoopr ok, would you want to make a PR for layer placement then? |
On closer inspection
The present_to_transaction implementation in this pull request is I think fine, and I think the option should be exposed for those who want to utilize it. Might warrant some extra testing, as:
|
Are you going to put this in for 0.8? Its a (small) api change |
@scoopr I thought this is internal API for gfx-backend-metal, not gfx-hal exposed. So we could add this API in a non-breaking way at any point. |
bors r=scoopr |
Add a presentation path that forces CoreAnimation transaction.