-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OffscreenCanvas new commit() and DedicatedWorker.requestAnimationFrame #288
Comments
The one thing of note here is that An alternative could be that we don't expose them in agent clusters that contain a service worker agent or shared worker agent, but that would require more IDL infrastructure. Noting this here as it sets some architectural precedent. (At least, I'm not aware of other APIs needing this.) |
Note that there's now a blink intent-to-ship thread for this feature |
So where is the up to date spec? The spec linked above says
and
But talking to others (and in testing) these are no longer the case. For an Example: This renders to the canvas. no call to in worker
In main thread
https://jsfiddle.net/greggman/w3t0gmvz/ The same is true for Canvas2DRenderingContext. Changing the code above to use canvas 2d instead of webgl also renders which the spec linked requires it NOT to render. in worker
https://jsfiddle.net/greggman/qmn2e78h/ Also the spec linked says and
But that is also false. Change the code above to
and we see the intrinsic size is updated without calling commit https://jsfiddle.net/greggman/j3pgLs0o/ Where is the correct spec and has it been reviewed? |
@greggman part of this review process is to help align implementations with the spec and the spec to implementations. As you point out, clearly there are some discrepancies between the two. It also looks like this is not shipping [yet] in any release version of a browser (e.g., not behind a flag), so there's still an opportunity to get alignment. :) |
@fserb some initial feedback from TAG review today: This looks like great progress, and is addressing the high-level feedback about having a consistent requestAnimationFrame from our prior feedback. In general, we'd like to see more code examples in the describing document, especially code examples that highlight (at a high-level) the various use-cases outlined at the top (it is an "explainer" document, right?). With our privacy hat on, we were disappointed to not see a Privacy considerations section :-( It would be great to add one, even if you believe there isn't much to put in it--it helps us know you've given it some thought. @annevk left some feedback above about availability in agent clusters... the behavior of which is a side-effect of integration into the spec via the PR. My personal view is that the updated Also as-noted, the PR has nothing for the A nit: the WebIDL description of Offscreen canvas' Use case question: is composition a desired scenario? E.g., Worker+Offscreen canvas used to render the background of a 3D scene, while foreground rendering done on Window's browsing context and the two scenes are composited together? (Or foreground paints a player HP/MP/Score overlay, while offscreen canvas renders the game world?) In the description of the processing model: "atomic update" text is used, but there's a lack of clarity on what it means. Does it mean a blocking synchronization point for the window's browsing context? There may be a definition of this in the 'Previously Considered Solutions' section, but I don't have confidence that that definition wasn't thrown out with the previous solution. :) Also, processing of the Offscreen Canvases is done after other animation callbacks are executed in window's browsing context. Is there a specific reason for that (other than arbitrary)? Is it to avoid blocking more of the event loop?) Also, I assume this processing is somehow recursive over the tree of potentially nested workers (as workers can spawn workers). Relationship of commit() to ImageBitmap... are these duplicating effective behavior? ImageBitmap can allow multiple frames to accumulate in memory before being rendered (these pinning GPU memory until collected). Is ImageBitmap still a good pattern to use when commit() is available and can seemingly do the same transfer-and-display logic without using intermediate objects and without allowing for the possibility of unbounded GPU memory backpressure? commit() + rAF behavior: Is the expectation that commit() must be used at the end of each worker's rAF? (in order to get the timing synchronized and send the frame at the appropriate time to the GPU?). If not, is there some assumption that all offscreen canvases implicitly commit at the end of the worker's rAF call? This was put in question by @greggman above and does need to be clarified. From the PR: Note: this PR seems incomplete to me... maybe because the explainer document is incomplete? Based on what I've seen, I certainly don't think this is ready to ship... line: 89072 - seems to loose to just say "user agent decides" for the spec--doesn't it need to match the framerate of the associated window's browsing context? Must have missed where that was set-up... |
@travisleithead I don't think you understood my point. It's not about exposing it outside of dedicated workers, it's about which dedicated workers. E.g., dedicated workers spawned from service workers. Are they exposed there or do they throw? |
I don't know who's reading what where but on top of the issues mentioned above with The biggest issue is that
Once you do that all access to all other APIs stops working in that worker because all other APIs are event based (onmessage, fetch, websockets, rAF, setTimeout, setInterval, etc...) Is that fact well under by the people reviewing this proposal? The people pushing for It seems like there are a bunch of issues with that direction. For example it seems to make throttling hard. You can block the commit indefinitely when the page using it is not the front tab BUT, if you block then any other workers or the main thread will suddenly stop having their shared arraybuffer exchanges respond. While it might be possible to correctly program for that case I have a feeling it will lead to tons of subtle race conditions for most apps trying to use it. It was also suggested in that case that instead of blocking the browser might just throttle (eg. only process commit once a second) but that also seems like a bad idea as it will likely make using the browser extremely unresponsive until the tab using the spin loop is closed. |
The last I understood was that Browsers should not block The issue with multithreaded applications is that only one Worker in such an application might be doing OffscreenCanvas WebGL rendering, and many other Workers in an app may be doing some other continuously running computation, that can produce and wait for events from the OffscreenCanvas WebGL rendering Worker. If just the OffscreenCanvas Worker paused in If we think that a computation consists of two separate logical parts: If we wanted something more automatic on the cooperative front, it could be a property For slightly easier rendering throttling management, it might be nice for But apart from that, I don't think browsers have any other option than to globally throttle all Workers/the whole tab, independent of what they are doing. It is the same problem as how should browser react to |
I'm glad alternative solutions are being considered. I'd like to take a step back and suggest that maybe the goal of allowing unmodified native apps to run um ... unmodified is maybe not such a great goal for the web? Native apps have all kinds of issues when ported to the web. Some issues off the top of my head
What these and other issues mean is that bringing native apps to the web and having the experience be good for the user requires lots of work. If that work is not spent then all users get is really poor experiences turning them off to the web. The amount of work to refactor these apps to be event driven is tiny compared to the amount of work required to make them good experiences on the web. In other words, this goal of making spin loops magically work is basically saving native apps only a few percent of the work they really need while at the same time encouraging bad experiences for users since native app people can then just barf out their apps, no thought given.
That doesn't seem like a win for anyone. Just for fun I went looked up the code for Lumberyard and Unreal main calls RunMainLoop RunMainLoop Checking Unreal WinMain calls GuardedMain GuardedMain In either case I doubt it would take more than 1-4 hours to throw in a few statics and/or singletons to take things off the stack and expose the main loop to be event driven. That matches my own experience of making a few native apps event driven. In my case it took 20-40 minutes. It seems arguable that if native devs aren't willing to put in that small amount of time to make their apps event driven then they aren't likely to do any of the other work required to bring their app to the web and so this path of supporting spin loops is only really enabling bad experiences from thoughtless quick and dirty recompiles instead of thoughtful ports. Anyway, just a thought. |
There are many scenarios where native applications drive their threads using internal synchronization (mutexes / futexes, lockless algorithms, work stealing) where it is either impossible or impractical to change the threading model to be event driven. Being able to bring applications like these to the sandboxed and portable web environment is a benefit to users because it makes them easier to run, and Emscripten. asm.js, and WebAssembly have successfully brought many apps to the web's ecosystem already. We plan to continue prototyping the ability to process pending tasks as a compatibility and interoperability mechanism with native codebases. |
CC issue #141 Hey all, Took this up again at today's F2F in Paris. Thanks for patiently explaining a complex space to us. While we recognize the scenarios for having an explicit blocking Shared Array Buffers and atomics now allow developers to guard critical sections, and that may seem in conflict with a rAF-based solution, but the extent to which that is true isn't clear from discussion or the examples we've been able to read. One of the most complex scenarios we've been pondering has been the need to run multiple displays at different rates, driven from the same GL context. This arises in VR and XR scenarios and we're very happy to see the progress made in providing This progress in XR takes a lot of the pressure off of the necessity of Cheers -- Alex & Travis |
Per the above, to clarify, we want to close this out, noting that we're happy that Looking forward to hearing back about what you'd like to do next. |
We're actively working on a port of a large multithreaded game engine to the WebAssembly environment. @kainino0x and @nickshinpho are driving this effort. Once we have this working as expected, we will compare the approaches of commit() vs. an API which provides broader compatibility of web APIs to WebAssembly's threads (http://crbug.com/869569). One of these two approaches will definitely be needed, and the determining factor will be performance of the overall system. We'll come back to this thread after we've done these measurements and indicate which direction we would like to pursue in collaboration with the TAG. |
Bumped this into the new year to come back and check it then. |
We discussed briefly at the f2f and agreed to close this for now. Can be re-opened if required. |
The commit() method of OffscreenCanvas contexts was controversial and has not been shipped by any browser. Rewrite the OffscreenCanvas tests to not require it. For background, see: w3ctag/design-reviews#288 https://groups.google.com/a/chromium.org/d/topic/blink-dev/hRZ_P2o-aEk/discussion
The commit() method of OffscreenCanvas contexts was controversial and has not been shipped by any browser. Rewrite the OffscreenCanvas tests to not require it. For background, see: w3ctag/design-reviews#288 https://groups.google.com/a/chromium.org/d/topic/blink-dev/hRZ_P2o-aEk/discussion
Searching for word "commit" on this page https://html.spec.whatwg.org/multipage/canvas.html#the-offscreencanvas-interface still finds a ton of hits, so I wonder, should this bug be reopened, or a new one created, to remind to update the OffscreenCanvas spec to remove the commit() text? The spec being out of date on commit() makes me wonder if there are other parts in the OffscreenCanvas spec that are out of date? According to https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/OffscreenCanvas Chrome already says they would be shipping OffscreenCanvas, but if the spec is still in flux, what exactly is Chrome shipping? |
OffscreenCanvas was shipped in Chromium, without the I agree it should be removed from the spec, will follow up with @fserb . |
Hello TAG!
This is a follow up from: #141
I'm requesting a TAG review of:
This change addresses concerns pointed out at #141, namely:
Promise commit()
solution doesn't exist anymore, insteadrequestAnimationFrame
has been added toDedicatedWorkerGlobalScope
, and a render model has been described on it. This is semantic similar to what happens onWindow
(although not attached to a Document animation frame).commit()
function, to support the new WebAssembly cases of a busy loop execution (that doesn't finish the context task) but that still wants to commit a render frame. This newcommit()
is a blocking function that returns as soon as the UA is ready to receive a new rendering of the OffscreenCanvas.We'd prefer the TAG provide feedback as leave review feedback as a comment in this issue and notifying myself (@fserb) if needed.
The text was updated successfully, but these errors were encountered: