mercredi 26 février 2020

Web worker with web assembly as main loop and javascript callbacks

I am porting an application that generates frames of graphics to display. Think something along the lines of game of life. The main loop is deeply nested and I compile the C-program to a webassembly. In the C-program, I make callbacks to javascript using EM_ASM like this:

    EM_ASM({
        SysDrawMap($0, $1, $2);
    }, (int)Used.MapWidth, (int)Used.MapHeight, imagedata);

This works. I get the frame and can render it. Problem is, this blocks the main thread so I never get to see the result and the browser is locked until the simulation is over.

So I moved the code to a web worker and had it load the C-program and post the images to the main thread using the postMessage queue system. On the main thread, I received the images and updated a canvas. This sort of worked. Problem is, the worker created frames too fast and filled the queue with images (huge memory consumption) and the main thread stalled trying to receive the images.

So I have to throttle the producing side somehow, but not in a way that causes too much slowdown. I am thinking about a 5-10 frames queue buffer, but how can I do that without rewriting the main loop(s)?

In the worker, when it posts the images to the queue, it has no way to receive messages as control goes directly back to the C-program, and while it works, the worker still wont receive messages.

I can't even make a pause button, as the web assembly runs full speed ahead without any knowledge of the messages in the queue. And there doesn't seem to be a way to check the number of messages in the queue and either side.

I fear my only solution is to rewrite the C-program deeply nested loops so I can call from javascript to web assembly and have 1 frame generated. But would that solve it? I would have an endless while loop calling the webassembly, which I take will also block reception of new messages. There wont be any idle time until the web assembly has run its course.




Aucun commentaire:

Enregistrer un commentaire