Nazariglez / notan

Cross-platform multimedia layer
https://nazariglez.github.io/notan-web/
Apache License 2.0
763 stars 53 forks source link

lazy_loop does not update with `request_frame()` on Windows #303

Closed woelper closed 5 months ago

woelper commented 6 months ago

When running the following code derived from the basic egui example, no updates happen when app.window().request_frame(); is called. This seems to happen on Windows only. I suspect this is a regression since I think this was working well before.

use notan::egui::{self, *};
use notan::prelude::*;

#[notan_main]
fn main() -> Result<(), String> {
    let win = WindowConfig::new()
        .set_vsync(true)
        .set_lazy_loop(true)
        .set_high_dpi(true);
    notan::init()
        .add_config(win)
        .add_config(EguiConfig)
        .draw(draw)
        .build()
}

fn draw(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins) {
    let mut output = plugins.egui(|ctx| {
        egui::SidePanel::left("side_panel").show(ctx, |ui| {
            ui.heading("Egui Plugin Example");
            ui.spinner();
        });
    });
    output.clear_color(Color::BLACK);

    if output.needs_repaint() {
        gfx.render(&output);
    }
    app.window().request_frame();
}

Test repo here:

https://github.com/woelper/notan_lazy_test

Nazariglez commented 6 months ago

I need to take a look into this, however, meanwhile, did you try to remove the if output.needs_repaint() line? My guess is that is returns false and then is drawing nothing while the frame is still happening.

woelper commented 6 months ago

Thanks for your answer!

I just tried without if output.needs_repaint() and it also does not update (the spinner is stopped in the example).

This is the code I tried:

fn draw(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins) {
    let mut output = plugins.egui(|ctx| {
        egui::SidePanel::left("side_panel").show(ctx, |ui| {
            ui.heading("Egui Plugin Example");
            ui.spinner();
        });
    });
    output.clear_color(Color::BLACK);
    gfx.render(&output);
    app.window().request_frame();
}
Nazariglez commented 5 months ago

This should be fixed now on the develop branch, at least it seems to me that it works the same on linux, macos, and windows.

Using a spinner doesn't work quite well with lazy loop because the spinner requests an update to egui, and egui requests an update to notan, so with this fix you will see how it's always rendering even if you don't call request_frame manually. But you can remove the spinner, and put a text with app.timer.elapsed_f32().to_string() somewhere, and then test both manual update and lazy (only when events are triggered).

Thanks for reporting the issue and do not hesitate to reopen if something feels wrong!