-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
What *is* Canvas desynchronized attribute? #5466
Comments
CC @jdashg , @kenrussell , @kainino0x |
FWIW, cf529a3 should link to more context. |
I believe everything you said is correct. It should be possible to get just the DOM-decoupled behavior by rendering through transferControlToOffscreen(), even on the main thread.
As it can go through a very different compositing path, on some systems I think the alpha=false problem wouldn't present an issue (e.g. with front-buffer rendering). But on systems where desynchronized=true doesn't have an effect (or is implemented differently), the alpha=false requirement could definitely still be an issue. AFAIK there's unfortunately no way to determine what the best configuration is going to be for a given system, right now. |
@juj good questions and observations - I also think your four points about what
As @kainino0x points out, the best approach to decouple the presentation of WebGL's rendering from other HTML composition is to use |
Trying to understand what the Canvas WebGL/2D context creation
desynchronized
attribute is, and what are the pros and cons of using that attribute.It is clear that the benefit is that "drawing will go faster" and/or "drawing will have less latency". Everyone always wants faster operation, less latency and less overhead, so the attribute sounds great. But there must be a drawback, or otherwise we would not need an attribute at all, but would just always enable it.
What is the drawback?
Reading the wordings of the spec from different sources, I am getting confused by the following ways that I find being able to interpret the spec:
[1] states
This wording suggests that
desynchronized
is/can be an optimization where browser is allowed to detach canvas rendering to occur decoupled/faster than some internal in-order buffering of the browser event queue.Drawback: Painting may appear out of order with respect to other observed web events(?)
[2] states
The mention of tearing artifacts suggests that
desynchronized
is/can be implemented as a vsync disabled flip mode.Drawback: Scanline tearing when presentation occurs without waiting for vsync vertical refresh.
[3] states
This suggests that
desynchronized
is/can be implemented by browser as a front buffer only rendering mode, where the swap chain does not even contain two buffers to do double buffering. Note that WebGL 3D & 2D canvas (sprite) renderers do not work in a top-down scanning fashion, so in front buffer rendering mode, the rendered objects can appear one by one on the screen as they are drawn e.g. back to front.Drawback: To ensure consistent view of full "final" images only, one will need to implement double buffering manually if rendering algorithm is complex (e.g. a
clear(); for(sort(objects, backToFront)) draw(object);
Although actually doing front-buffer rendering seems pretty radical for web. Perhaps instead, wording in [3] was off-by-one, and intended to read that
desynchronized
is/can be implemented by UA as double-buffering instead of triple-buffering? (the original namelowLatency
suggests that it would be an optimization that avoids an extra buffer copy) In that case,Drawback: the usual that comes with double-buffering instead of triple-buffering: if one buffer has finished rendering, and another one being presented, the CPU must pause until next vsync to get a new buffer to draw to. In triple-buffering mode, the CPU can drive a third frame with a GPU while one is being shown, and another one is in the queue.
Reading the technical prose for Chrome at [4],
suggests similar to [1], that in Chrome at least
desynchronized
is implemented as a way that the Canvas swap can occur independent of the rest of the page composition swap.Pros: Skips an intermediate surface blit from canvas -> page -> screen, and goes directly canvas -> screen?
Drawback: a. Requires setting
alpha=false
on WebGL contexts. Both Chrome and Firefox developers have recommended before that WebGL contexts should never be created withalpha=false
due to performance problems with 24-bit RGB memory layout (though I am not sure whyalpha=false
could not be implemented as RR8G8BB8X8 as opposed to R8G8B8A8, but that is well beyond this bug)b. The internal Chrome doc states a very important constraint that should be part of the public spec if this constraint still holds?
WebGL has had a property that if one does not perform any WebGL API draw calls within a
requestAnimationFrame()
body, then that loop tick should not present anything (e.g. a black screen) but it should keep the old contents. The above sentence suggests that underdesynchronized
, that is no longer the case, but a WebGL page should render a new frame in every singlerAF()
tick?sidenote: is [4] out of date? The code example there has
but this
lowLatency: true
did not make it? Should it beIn summary, putting all of the documentation [1]-[4] together,
desynchronized
can enable in an UAWhat of this is correct? Did I misinterpret some of the spec wording?
Which of the above drawbacks can one have? Should I double-buffer my painter's algorithm page manually (e.g. in a WebGL FBO) if I want to use
desynchronized
and avoid the back-to-front rendering showing up? Should I expect to observe vsync tearing?If I am not implementing a 2D digital artist pen paint application, nor a VR application, but a regular game-type WebGL application, should I look at using
desynchronized
?reduces the latency and power consumption even further
suggests that it would be a great way to save power especially on mobile.desynchronized
means [1] and app does not care about getting events queued in synchronization, then it would be a nice small latency win.desynchronized
means "vsync off", like [2] suggests, it would mean visual glitching on the output.desynchronized
means "front-buffering only", like [3] states, would it still be faster to use it, and flip FBO->canvas manually?desynchronized
means "must render at each rAF() tick", cannot use it if app is not configured for it (Emscripten OFFSCREEN_FRAMEBUFFER case)desynchronized
requires usingalpha=false
, would any performance benefit be worth it given thatalpha=false
has performance problems (at least in Chrome)?The text was updated successfully, but these errors were encountered: