floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.82k stars 475 forks source link

First draw on mac take lot of time #871

Closed dazkzi closed 1 year ago

dazkzi commented 1 year ago

On m1 mac, there is no such problem. But on other mac, this problem is significant.

void frame(void) {
    uint64_t start_time = stm_now();

    static int i = 0;
    i += 1;
    sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height());

    sg_apply_pipeline(state.pip);
    sg_apply_bindings(&state.bind);

    sg_draw(0, 3, 1);

    sg_end_pass();
    sg_commit();

    uint64_t anim_eval_time = stm_since(start_time);
    float frame_time = stm_ms(anim_eval_time);
    printf("%d %fms\n", i, frame_time);
}

It takes too much time to render first frame.

1 39.920799ms
2 0.045633ms
3 0.023270ms
4 0.030027ms
floooh commented 1 year ago

There's not much I can do there unfortunately, it's probably some stuff that needs warming up inside Metal or MTKView.

FWIW I've seen funky swapchain timing behaviour on macOS since forever, mostly when a window becomes obscured or visible. For instance when a window becomes fully obscured, MTKView doesn't trigger the frame callback for a full second, and macOS/MTKView also changed behaviour multiple times about triggering the frame callback for obscured windows.

And without MTKView (using CAMetalLayer directly), there's the opposite problem that throttling to the display refresh rate doesn't work for up to half a second in a newly created window or when a fully obscured window becomes visible.

TL;DR: under-the-hood behaviour like this changes unpredictably quite frequently between macOS versions unfortunately.

dazkzi commented 1 year ago

This only happens when use OpenGL. Metal is fine.

floooh commented 1 year ago

Ah ok, on macOS OpenGL is implemented on top of Metal though, so it's just more stuff heaped on top. But the same thinking applies, there's probably some warmup stuff that happens in the OpenGL implementation during the first frame.

(OpenGL in general behaves completely unpredictable when it comes to timing, on all platforms).