Skip to content

anyrender_skia: smooth resize on mac#50

Open
jrmoulton wants to merge 1 commit intoDioxusLabs:mainfrom
jrmoulton:push-mvuolwokpsol
Open

anyrender_skia: smooth resize on mac#50
jrmoulton wants to merge 1 commit intoDioxusLabs:mainfrom
jrmoulton:push-mvuolwokpsol

Conversation

@jrmoulton
Copy link
Contributor

@nicoburns could you test this with blitz?

Winit is still a bit weird about frame lifecycle but this is much more likely to have a smooth resize on Mac

@jrmoulton
Copy link
Contributor Author

skia-mostly-smooth-resize.mp4

in floem

@nicoburns
Copy link
Contributor

Hmmm... it doesn't seem perfectly smooth in Blitz:

Screen.Recording.2026-03-14.at.18.50.44.mp4

Not sure if it's slightly better or no different.

@jrmoulton
Copy link
Contributor Author

Might not be different for blitz. In Floem I've recently made a change to actively redraw the window while resizing without waiting for winit to deliver the window resize event and that has made it so that I can get smooth resizing. but without these changes resizing is very bad

@nicoburns
Copy link
Contributor

In Floem I've recently made a change to actively redraw the window while resizing without waiting for winit to deliver the window resize event and that has made it so that I can get smooth resizing. but without these changes resizing is very bad.

That sounds cool! Where are you getting the resize events from?

@jrmoulton
Copy link
Contributor Author

jrmoulton commented Mar 14, 2026

pub(crate) fn render_frame(&mut self) {
    let renderer_ready = matches!(self.paint_state, PaintState::Initialized { .. });
    if self.window_state.request_paint && renderer_ready {
        self.window_state.request_paint = false;
        self.paint();
        self.last_presented_at = Instant::now();
    }

    if self.live_resize_active() {
        self.window_state.schedule_paint(self.id);
        self.window_state.request_paint = true;
        self.window.request_redraw();
    } else {
        self.live_resize_until = None;
    }

    // Keep animation control flow in sync with scheduled updates.
    let window_id = self.window.id();
    if !self.window_state.scheduled_updates.is_empty() {
        add_app_update_event(crate::app::AppUpdateEvent::AnimationFrame(true, window_id));
    } else {
        add_app_update_event(crate::app::AppUpdateEvent::AnimationFrame(false, window_id));
    }
}

when rendering a frame if there was a resize event in the last 100 ms (that number could probably be optimized). just just schedule a redraw. This obviously isn't a perfect fix and still stutters if the frame deadline is missed but resizes are less likely to jitter. I'm not sure why this improves things (I would honestly expect it to make it worse) but I noticed that while animations are running and actively requesting frames resizes are always smooth (as long as frame deadlline is still met). wgpu max_desired_frame_latency needs to be set to 1 (although I keep Vulkan at 2 but that needs tested).

when winit was working on the presenting of frames it seems they were doing it while always drawing a new frame at vsync. matching that seems to help

@nicoburns
Copy link
Contributor

Interesting. You may also be interested in emilk/egui#7641

@jrmoulton
Copy link
Contributor Author

ah that's insightful

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.

2 participants