-
Notifications
You must be signed in to change notification settings - Fork 133
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
internal/glimpl: [wasm] remove syscall/js #4
Conversation
cd87e2b
to
60829a4
Compare
I forgot to include the |
The No one asked, but I will answer... 1. Why not 2. Why create The Furthermore, the Using 3. Why drop 4. Where is the GC? Why not use Yes, each 5. Why have a shared string buffer? The string cannot be larger than 4096 bytes, that seems enough for us. It is not threading safe, but WebGL does not seems to be thread-safe either. 6. That works? I test it against multiple devices and multiple conditions (WebGL 1-only, WebGL 2-desabled, WebGL 2) and on multiple devices that I have available, also using the BrowserStack. Far I tested, it works even on Firefox 53 (2017-04-18), and Chrome 63 (2017-12-05) and Safari 12. So far, the browser-support seems on par with the current Gio version. I tested with the "Kitchen" and my own app, only. |
60829a4
to
c962b7d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3. Why drop
js.Value
?
Mixingjs.Value
and custom JS is dangerous. The older patch does that quite well, but at first it works on Go 1.15 and not on Go 1.14. So, trying to make it compatible withjs.Value
is not worth.
Can you elaborate what makes mixing js.Value and low-level javascript assembly dangerous, or at least more dangerous than your custom syscall approach? As far as I can tell, this argument blocks leaving performance insensitive function using the slower but safer syscall/js.
internal/glimpl/gl_js.go
Outdated
} | ||
func (f *Functions) Uniform2f(dst Uniform, v0, v1 float32) { | ||
f.Ctx.Call("uniform2f", js.Value(dst), v0, v1) | ||
vv0, vv1 := float64(v0), float64(v1) // Float32 doesn't work | ||
f.Ctx.Call(_glUniform2f, uintptr(unsafe.Pointer(&dst)), uintptr(unsafe.Pointer(&vv0)), uintptr(unsafe.Pointer(&vv1))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uniform etc. are uints. Won't all these &value pointer taking expressions lead the values to be heap-allocated and thus subject to garbage collection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are right, did you have any idea to avoid it? Using []interface
seems to have the same issue, actually even worse. I need to get the pointer anyway.
About the float64()
it's also done internally by the syscall/js
, https://github.com/golang/go/blob/master/src/syscall/js/js.go#L162-L221. I'm trying find a way to read the float32
directly on the JS too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment about generating the assembly stubs.
Well, the Anyway.... Let suppose that The The oposite is even worse, if The The current patch doesn't have to match any flag with the In general currently we only need |
c962b7d
to
0289d07
Compare
I forcepush just to replace the Float64 to Float32, avoiding the |
Indeed, any syscall/js is slow. I hope to avoid it where the slowness is in the per-frame hot path.
To make the discussion clearer, I added a sketch of an approach that should be compatible with both syscall/js and whatever faster assembly approach we end up with, by storing both a js.Value and an integer reference for each object: https://git.sr.ht/~eliasnaur/gio/commit/cf926a7491a63a7cfddb530f4f93bcabf6930700 WDYT? |
I'm not sure if that is worth it. I don't think it solves any issue:
But, additionaly:
I use something similar here: 0289d07#diff-bf9a8e77af361576a7335f1f62097cd39db03ab401616e81df00a3a9be5aa46dR168-R170 The I'm not sure if I agree with the idea of "just replace slow functions". There's a lot of calls to WebGL, every single frame. For me, all functions must be as fast as possible. Also, let's consider that we have six slow functions, such as BufferData, CheckBufferframe, ReadPixel, EnableVertexAttribArray, VertexAttribPointer and Viewport. In the end, we will have 6 JS functions, 6 assemblies (and some additional overhead due to the another I'm not sure why you are so worried about dropping the
The current PR has only five functions. If it has some bug will be easier to spot than the older one, since all WebGL functions are using the same This PR is working on the new Go1.16Beta1, without any change. |
Sure, avoiding syscall/js means tinkering with internals. The goal is to minimize the tinkering.
Yes, but only on creation (and deletion) of objects, which is already expensive. The GPU backend takes care to re-use GPU objects.
Again, only during deletion which is a rare occurrence.
Indeed. I'm proposing to expand that facility to all GPU objects, and to keep a struct of both the js.Value and fast integer reference.
It's true that a lot of calls are per-frame and need assembly implementation. However, with the dual js.Value/ref approach we're not bound to all-or-nothing. As a side bonus, I don't think any performance critical functions use string parameters, so we can omit string handling entirely.
I argue that the 4.5ms gain can be achieved with fewer functions replaced.
The entire WASM port is experimental :) However, can we agree that syscall/js is safer than any other approach?
Ok. I admit that your latest revision does look a fair bit less scary than previous revisions, and I think I can be persuaded to replace all of syscall/js. However, there are two issues I'd like to see fixed:
I believe both issues can be solved by |
I thought about that, but the current
I'll try to build some proper generator. |
No, non-pointer parameters don't create garbage.
|
While restructuring the GL backend for the new renderer, I discovered that the WebGL backend has been passing much more data than intended (the entire cached byte buffer, not just a slice of it). See https://gioui.org/commit/e012c3f393792 for the fix. It should speed up buffer(Sub)Data and friends. |
3ac8449
to
d688673
Compare
899f0fa
to
94f7fa3
Compare
0b4b89b
to
8d8c105
Compare
I'm parking the code here. The generator is very poorly written, I tried to use the There's some changes, that I think not belong to here. I add some cache to To use the asm version, must use I don't think it will be accepted in Gio core, but I'm using that patch. :\ |
99bd349
to
126c88b
Compare
In the beginning of each frame, multiple calls to `GetInteger`/`GetFloat` is performed, taking around ~2ms out of ~8ms. Now, those data are cache at first usage, avoiding calls to JS. It saves around ~2ms out of ~8ms. Due to `syscall/js` usage of `TextEncoder`, which is slow on Chrome, a new cache was created, to bind function and use `Invoke` instead. It saves around ~1ms out of ~8ms. In total, this patch improves the performance from ~8ms to ~5ms. It still slower than gioui#4. Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
8bf1cd4
to
eb637b9
Compare
eb637b9
to
16fe252
Compare
Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
16fe252
to
d6983ce
Compare
8ae0153
to
3f38e67
Compare
- This is the 1st commit message: ScrollTo, PagePrev/Next, etc This is a combination of 5 commits. - layout: add List.ScrollTo, ScrollPages, and 2 more Also add PagePrev & PageNext. Include tests for all. - app,app/internal/window,io/system: macOS menus A strawman interface to the macOS menuing system. - Make menus compile on other architectures - app/internal/window: Add modifiers to macOS menu event - Update to latest Gio main - This is the commit message gioui#2: Delete app/internal/wm/window.go No longer used in main branch. - This is the commit message gioui#3: Move menu changes into their own files. - This is the commit message gioui#4: io/key,widget: Make editor hotkey filter more specific Only look for up/down/pageup/pagedown if the editor is multiline. Only look for enter/return if the editor is Submit == true. Fix modifier for delete-backward & forward. Implement some key.Set builder functions and use them in the above code. Fixes: https://todo.sr.ht/~eliasnaur/gio/399 - This is the commit message gioui#5: widget: Tweak editor hotkey event listener For delete-forward and backward, only listen for ShortAlt. Only listen for Short-[C,X] (copy selection and cut selection) when there's a selection. - This is the commit message gioui#6: Add system.MenuEvent to Window.processEvent - This is the commit message gioui#7: key: rename BuildKeySet and BuildKeyGroup to BuildKeyset and BuildKeygroup. - This is the commit message gioui#8: Sleep 2ms after onClose. Signed-off-by: Larry Clapp <larry@theclapp.org>
- This is the 1st commit message: ScrollTo, PagePrev/Next, etc This is a combination of 5 commits. - layout: add List.ScrollTo, ScrollPages, and 2 more Also add PagePrev & PageNext. Include tests for all. - app,app/internal/window,io/system: macOS menus A strawman interface to the macOS menuing system. - Make menus compile on other architectures - app/internal/window: Add modifiers to macOS menu event - Update to latest Gio main - This is the commit message gioui#2: Delete app/internal/wm/window.go No longer used in main branch. - This is the commit message gioui#3: Move menu changes into their own files. - This is the commit message gioui#4: io/key,widget: Make editor hotkey filter more specific Only look for up/down/pageup/pagedown if the editor is multiline. Only look for enter/return if the editor is Submit == true. Fix modifier for delete-backward & forward. Implement some key.Set builder functions and use them in the above code. Fixes: https://todo.sr.ht/~eliasnaur/gio/399 - This is the commit message gioui#5: widget: Tweak editor hotkey event listener For delete-forward and backward, only listen for ShortAlt. Only listen for Short-[C,X] (copy selection and cut selection) when there's a selection. - This is the commit message gioui#6: Add system.MenuEvent to Window.processEvent - This is the commit message gioui#7: key: rename BuildKeySet and BuildKeyGroup to BuildKeyset and BuildKeygroup. - This is the commit message gioui#8: Sleep 2ms after onClose. Signed-off-by: Larry Clapp <larry@theclapp.org>
That change avoid JS calls through
syscall/js
. Instead we use theWebAssembly imports, which is defined on the
gl_js.s
andgl_js.js
.That change is similar to the previous patch, but it's easier to read
the code and fix. It also have only five JavaScript functions, instead
of one function for each WebGL call.
Opera 72 (w/ AMD Ryzen 3900X): ~8.0ms per frame to ~3.4ms;
Chrome 87 (w/ Snapdragon 435): ~83.2ms per frame to ~39.8ms;
The
gl_js.js
file is embed by thegogio
compiler.Signed-off-by: Inkeliz inkeliz@inkeliz.com