Skip to content
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

Surface lags behind on window resize #3756

Open
nohenry opened this issue May 7, 2023 · 8 comments
Open

Surface lags behind on window resize #3756

nohenry opened this issue May 7, 2023 · 8 comments
Labels
api: metal Issues with Metal area: wsi Issues with swapchain management or windowing platform: macos Issues with integration with macos type: enhancement New feature or request

Comments

@nohenry
Copy link

nohenry commented May 7, 2023

Description
When resizing the window, the wpgu surface does not keep up with the size of the window. This is possibly a problem with winit instead.

Repro steps
Run any example in the wgpu/examples folder

Expected vs observed behavior
I expect the surface to resize exactly to the current window dimensions:

Screen.Recording.2023-05-07.at.1.11.19.PM.mov

But instead the surface lags behind the current window size:

Screen.Recording.2023-05-07.at.1.09.50.PM.mov

Platform
This is running on MacOS Ventura (Metal). Using wgpu on v0.16 git
I've not tested on Windows or Linux.

@nohenry
Copy link
Author

nohenry commented May 7, 2023

Found the solution:

#[cfg(target_os = "macos")]
unsafe {
    surface
        .surface
        .as_hal_mut::<wgpu_hal::api::Metal, _, _>(|surface| {
            if let Some(surface) = surface {
                surface.present_with_transaction = true
            }
        });
}

@nohenry nohenry closed this as completed May 7, 2023
@kpreid
Copy link
Contributor

kpreid commented May 7, 2023

If it's that easy, perhaps this should be available as a safe operation. Reopen this issue?

@nical nical reopened this May 9, 2023
@ifacodes
Copy link

If it's that easy, perhaps this should be available as a safe operation. Reopen this issue?

I agree, I feel like this issue has popped up a few times over the last few versions.

@nohenry
Copy link
Author

nohenry commented May 12, 2023

One thing I want to know is if this a problem on different platforms (also how easy it would be to fix for them). I can test on Windows 11 and maybe Linux.

In terms of implementation, would it be best to have a field in the SurfaceConfiguration that determines this behaviour? I suppose it depends if this issue arises in the surface for other platforms.

@kpreid
Copy link
Contributor

kpreid commented May 12, 2023

Another question is whether this should even be configurable, or just be the default. In other words: is there some situation where present_with_transaction should not be true? (For example, does it reduce performance when not resizing?)

@cwfitzgerald
Copy link
Member

present_with_transaction afaik really limits the amount of frames in flight to under one, so unless you're making a UI app or other thing that needs to be resized all the time, it should be false so that the gpu can run independently.

One thing I want to know is if this a problem on different platforms (also how easy it would be to fix for them). I

@Ocrap7 there are issues on other platforms as resizing is an inherently racy problem. Afaik, DXGI can't do a truly smooth resize, though you can get close. Unfortunately the solutions will likely be different on each platform as each compositor is different.

@jimblandy jimblandy added type: enhancement New feature or request api: metal Issues with Metal area: wsi Issues with swapchain management or windowing platform: macos Issues with integration with macos labels Jun 8, 2023
@timtom-dev
Copy link

Any update on this? #3626 removed surface.as_hal_mut() so I've had to resort to this unholy abomination to get smooth resize on macOS:

#[allow(invalid_reference_casting)]
unsafe {
    surface.as_hal::<wgpu::hal::metal::Api, _, ()>(|surface| {
        if let Some(surface_ref) = surface {
            // AHH! Converting '&' to '&mut'
            let surface_mut = &mut *(surface_ref as *const wgpu::hal::metal::Surface as *mut wgpu::hal::metal::Surface);
            surface_mut.present_with_transaction = true;
        }
    });
}

which is obviously not ideal. 😬

@madsmtm
Copy link
Contributor

madsmtm commented Aug 12, 2024

I've improved the rendering when resizing in #6107, but using present_with_transaction is still needed to make it perfect.

Instead of exposing this to the user, perhaps we could enable it automatically when -[NSView inLiveResize] returns true? This might be more overhead because we'll be doing it on each render, though maybe we can cache the value of inLiveResize? Of course, this would ideally be done in -[NSView viewWillStartLiveResize] and -[NSView viewDidEndLiveResize], but those are harder for wgpu to get access to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: metal Issues with Metal area: wsi Issues with swapchain management or windowing platform: macos Issues with integration with macos type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants