Skip to content

Constrain OffscreenCanvas with a placeholder canvas element #10112

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

Open
beaufortfrancois opened this issue Jan 31, 2024 · 8 comments
Open

Constrain OffscreenCanvas with a placeholder canvas element #10112

beaufortfrancois opened this issue Jan 31, 2024 · 8 comments

Comments

@beaufortfrancois
Copy link

What is the issue with the HTML Standard?

In Event loop processing model about workers at https://html.spec.whatwg.org/#event-loop-processing-model:worker-event-loop-2, Dedicated Worker is the only type of workers that get special treatment for having its rendering updated. I believe Shared Worker and Service Worker should be also be included so that specs like WebGPU that have support for all workers can plumb into Update the rendering of that ${type} worker section. See gpuweb/gpuweb#4465 (comment)

@Kaiido
Copy link
Member

Kaiido commented Jan 31, 2024

The specs currently explicitely disable rAF in SharedWorker and in ServiceWorker by checking at the substep 1. of your link if the global object is a supported DedicatedWorkerGlobalScope.

And to be supported means

So not only is this reserved to windows and dedicated workers, but it even excludes the dedicated workers that have been created from a SharedWorker.

I guess there is a bug in that we do expose OffscreenCanvas in all Worker scopes though.
Actually it does make sense to expose it in other scopes, but I'm wondering why you do need to hook to update the rendering? Currently all it does is to update the content of a placeholder <canvas> element. But in a SharedWorker or a ServiceWorker you will never have such a placeholder <canvas>.

[edit]: I now realize there is nothing preventing the transfer of such an OffscreenCanvas gotten from transferControlToOffscreen() using serviceWorker.postMessage(data, [canvas]) or sharedWorker.postMessage()... However from my quick tests it seems only Chrome does support doing so with ServiceWorkers, while Firefox and Chrome support it for SharedWorkers. So indeed, if we do allow transferring such DOM-weak-linked OffscreenCanvas, we should probably expose rAF there. But maybe we don't want to allow these in such contexts? Is there an use case for it?

Maybe someone from @whatwg/canvas may want to chime in.

@annevk
Copy link
Member

annevk commented Feb 1, 2024

@beaufortfrancois did you look into blame to figure out why things are constrained the way they are? Service workers in particular do not seem like a place that should have to care about rendering at all. Shared workers is also fraught I think as they can be associated with multiple documents each of which can have their own refresh rate. What should the refresh rate of the shared worker be?

I think the change to WebGPU should be reverted and we should look into potentially constraining OffscreenCanvas more.

@fserb
Copy link
Contributor

fserb commented Feb 1, 2024

What @Kaiido concluded seems right to me.

We've seen many reasonable use cases of OffscreenCanvas in ServiceWorkers, like folks trying to build resource icons or pre-loaded images on the fly ("hash default images", etc).

Regarding them being transferred, it does seem to me that the current set of constraints (Windows or Workers that are "children of a Document") seems reasonable to follow (i.e., you can only transfer if it's created from a Document, therefore those are the only ones that need some rendering update notion).

Apart from "easy to plug in on the spec", is there any reason why WebGPU content can't be updated without the worker having a "render update"?

@kainino0x
Copy link

kainino0x commented Feb 1, 2024

WebGPU is useful without a canvas, and we definitely want it in ServiceWorker/SharedWorker regardless. And if OffscreenCanvas is going to stay in these workers (I think it should), it secondarily validates that choice.

That to say, I think we can fix-forward in the WebGPU spec, because the error is very small (and has an inline issue attached to it already). We're already mostly correct in that we only define an interaction with rAF if the OffscreenCanvas is a linked one.

If indeed transferControlToOffscreen isn't valid to send to these workers, then we just have to remove the two hooks and leave a note explaining why only dedicated workers get this behavior. Which I agree makes sense.

@annevk
Copy link
Member

annevk commented Feb 2, 2024

Constraining transferControlToOffscreen() and its output seems like a reasonable solution to me. Having a weak reference to an element across process boundaries seems very sketchy.

We should probably require OffscreenCanvas with a placeholder canvas element to stay within the same agent cluster, just like SharedArrayBuffer.

@annevk annevk changed the title Event loop processing model doesn't say anything about Service Worker and Shared Worker Constrain OffscreenCanvas with a placeholder canvas element Feb 2, 2024
@annevk annevk changed the title Constrain OffscreenCanvas with a placeholder canvas element Constrain OffscreenCanvas with a placeholder canvas element Feb 2, 2024
@fserb
Copy link
Contributor

fserb commented Feb 2, 2024

This makes sense.

Just out of curiosity, did we even have the notion of agent clusters back when we added OffscreenCanvas?

@annevk
Copy link
Member

annevk commented Feb 3, 2024

There was something like it, but it was not as well understood and had some issues ("unit of related similar-origin browsing contexts"). OffscreenCanvas was added in 2016 and SharedArrayBuffer / agent cluster integration was added in 2017 (and then adjusted in 2020 for Spectre purposes).

@kainino0x
Copy link

We should probably require OffscreenCanvas with a placeholder canvas element to stay within the same agent cluster, just like SharedArrayBuffer.

I did not realize that SharedArrayBuffer had such a constraint. Matching that definitely makes sense!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

6 participants
@fserb @kainino0x @beaufortfrancois @annevk @Kaiido and others