[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Public WebGL] Resurrecting Update Scheduling



I’ve spent time mocking up some of my WebGL apps with Web Workers and the performance (both in terms of free time on the main thread now that the compute pressure is gone and in consistent timing) is amazing. The problem is that it’s incredibly expensive to move data around in the current Web Workers world. It’s impossible to do pixel processing, particle systems, or other data-heavy stuff in real time because of that cost. [aside: does anyone know any tricks for getting the most performance out of postMessage? Maybe I’m doing something bad :)]



Without going full-blown WebGL-from-background-thread, allowing access to pixel buffers and array buffers from the workers without performing copies would solve most of the issues. It would then be possible to do pixel processing (either dynamic texture creation or handling of feedback buffers), geometry construction (if doing dynamic stuff like particle systems/etc), and all the expensive app stuff (physics/visibility/animation/etc) off the main thread, and only pass the references to the buffers and small command lists. Today, with the requirements of moving things back and forth as strings or deep copies all that data-heavy stuff ends up costing more in overhead than actual execution, and there’s no way to win.


If you had the ability to cheaply move data between threads (no sharing required – so avoiding locks/etc), you could then do some clever tricks to make things easier. For example, you could expose the WebGL API to a worker that really just queues everything up in a command list that is later executed on the main thread during your paint callback – then the only thing being done on the js thread is a walk of the command list and the GL calls – which is trivially fast – and there’s little worry about overrunning frame times/etc.


As for implementation - maybe it’s something like copy-on-write semantics on arrays that are passed in messages, or the ability to make WebGL arrays immutable (so that you could do readPixels, .freeze(), then pass it off safely to the worker and back), etc. Of course then there are issues of expensive large allocations, and making things permanently immutable could be just as bad as making copies...

This behavior would of course be useful in tons of other places as well, allowing for things like browser-side compression, encoding/decoding, etc.


Advanced, yes, but that’s where WebGL starts to get *really* interesting :)



Ben Vanik

Live Labs / Seadragon


From: rocallahan@gmail.com [mailto:rocallahan@gmail.com] On Behalf Of Robert O'Callahan
Sent: Saturday, April 17, 2010 9:34 PM
To: Ben Vanik
Cc: Thatcher Ulrich; Kenneth Russell; public webgl; Chris Marrin; Vladimir Vukicevic
Subject: Re: [Public WebGL] Resurrecting Update Scheduling


There is no way to guarantee timely callback delivery for normal Web _javascript_, because even in an ideal browser implementation the Web's single-threaded programing model leaves you at the mercy of activities like parsing, layout and the execution of other scripts ("tasks" in HTML5 parlance), including scripts in some other documents.

Thus for normal Web _javascript_, I think an API like the one I proposed is the best you can do ... certainly a big improvement over setTimeout. All you get is a best-effort attempt to fire beforePaint before the browser renders each frame. If the browser is able to composite frames on a different thread from the page's JS thread (highly desirable), and the JS thread can't keep up with the compositing thread (always a possibility), then some beforePaint calls will be skipped, or complete too late, and the JS animation will skip frames. There is no way around this.

To do better than that, we could try to use Web Workers, because they can execute independently of those "main thread" tasks. Workers can't manipulate the DOM or do most of the other things JS animations would like to do. But we could create some kind of API to allow a worker to control a WebGL canvas. Then --- if the browser supports compositing page contents off the main thread --- you could get WebGL canvas animations onto the screen without being vulnerable to main-thread task latency. I see this is a rather advanced feature that most authors would not bother with, and thus relatively low priority.

"He was pierced for our transgressions, he was crushed for our iniquities; the punishment that brought us peace was upon him, and by his wounds we are healed. We all, like sheep, have gone astray, each of us has turned to his own way; and the LORD has laid on him the iniquity of us all." [Isaiah 53:5-6]