-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
Hosting Avalonia in WebAssembly #1387
Comments
It would be possible and we are currently considering our options. The major blocker is that HTML5 doesn't have a proper 2D drawing API, so Skia needs to be compiled to wasm and somehow linked to resulting application. The problem with linking is that Mono doesn't currently provide P/Invoke support for wasm target. Another problem is that P/Invoke means indirect calls (i. e. calls via pointer), while WebAssembly doesn't support indirect calls between modules. That means that Skia needs to be linked statically, so we'll need a custom Mono build. It would be easier with CoreRT, since it supports static linking out of the box, but they are still implementing MSIL instructions for wasm target, so it's not ready even for an experimental port. |
Sorry if this is an obviously terrible idea, but why wouldn't you use WebGL? |
@pmoorelegistek We will be using WebGL at some point. The problem is that WebGL by itself doesn't support drawing 2D vector graphics. So we need Skia anyway. |
Oh I see what you're saying. I didn't realize it lacked basic 2D drawing. I take it the plain HTML5 canvas doesn't have good enough performance either?
I've been watching this project for awhile and would love to help how I can. Getting this on the web would be the Holy Grail. (Befitting the name Avalon(ia))
Get Outlook for Android<https://aka.ms/ghei36>
From: Nikita Tsukanov
Sent: Friday, March 9, 12:30 AM
Subject: Re: [AvaloniaUI/Avalonia] Hosting Avalonia in WebAssembly (#1387)
To: AvaloniaUI/Avalonia
Cc: Peter N. Moore, Mention
@pmoorelegistek<https://github.com/pmoorelegistek> We will be using WebGL at some point. The problem is that WebGL by itself doesn't support drawing 2D vector graphics. So we need Skia anyway.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<#1387 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AMw7S1GOycAJX3aLJnlzy5xM6yq_KrTiks5tciGKgaJpZM4SR4pe>.
|
Hmm. The problem with compiling Skia to WASM is you'll lose any benefits of hardware graphics acceleration on the device. Browser will be doing all the math, painting pixels, etc. I don't know that you'd ever get anything close to 60fps with a complex UI. Have you tried just using the HTML5 Canvas or SVG? |
Skia can use OpenGL ES profile for hardware-accelerated rendering. Which is basically what is provided by WebGL. |
You're saying Skia / OpenGL will be able to access hardware acceleration (i.e. the GPU) after compiled to WASM? Are you certain about that? Everything I understand about WASM would lead me to think not. I would think you'd be better off using three.js - or better yet porting it to C# - wrapped around WebGL. I'd be happy to look into it some more and experiment. Do you have a working prototype using Mono-to-WASM at the moment with any rendering at all? |
Emscripten toolchain has complete support for WebGL. It might be a bit difficult to make it work with Mono since it has it's own js glue code, but other than that I don't see any issues. |
@danwalmsley it uses HTML. Avalonia can't be rendered with HTML. |
Is there are any try to use Skia/WebGL? Any branch for this experiment? |
if I understand right, what @kekekeks is saying is that it's not feasible at the moment because Mono can't use P/invoke to call the Skia functions. So while they can compile Skia to WASM, there would be no way for the .NET code to access it. What I don't understand fully, though, is why it has to be Skia. There are Javascript libraries that provide 2D drawing function wrappers over WebGL (e.g., https://threejs.org/). I'd think it at least worth an experiment to make a DrawingContext that wraps three.js and go from there. If that works, porting threejs to C# and simply including it in the Avalonia build would not be too bad of a project and would probably get you performance on par with Skia. |
@pmoorelegistek The main problem is the complete lack of a proper text measurement API. We can't get our TextBox to work if we don't have an accurate position of each individual symbol. Even for our TextBlock we need to be able to measure and lay out text lines properly. There is no way we can do that with the APIs available to JavaScript. |
I added an issue for pinvoke support on mono so this can be tracked. mono/mono#8007 |
It looks nice but what are we looking at exactly?
…________________________________
From: TONY HENRIQUE <[email protected]>
Sent: Thursday, April 12, 2018 6:38:15 PM
To: AvaloniaUI/Avalonia
Cc: Peter N. Moore; Mention
Subject: Re: [AvaloniaUI/Avalonia] Hosting Avalonia in WebAssembly (#1387)
See
http://www.noesisengine.com/webgl/Samples.Buttons.html
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<#1387 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AMw7S61hESqCLDWhVkG6jvegNBn7KHWtks5tn-VngaJpZM4SR4pe>.
|
Noesis has it's own rendering engine, if I recall correctly. A proprietary one. We don't have the resources to create a whole new 2D graphics library, so we are using an existing one, which is Skia. Until we have a way of linking it in on wasm target (be it Mono or CoreRT), we won't be able to get Avalonia working in the browser. |
Hey Nikita - since this thread keeps coming alive - And beyond that, I don't think a port of three js to C# - or at least enough of it for our purposes - would be at all that difficult. This is my company, and as you can see from our product we have a vested interest in your project: www.legistek.com |
Well, you see, the only text measurement API that I've found for HTML5 Canvas is measureText call which returns a TextMetrics object. The problem is that it doesn't support anything but text width: As you can see, "advanced" properties are only supported on Google Chrome and need to be explicitly enabled in browser settings. Getting text width is unfortunately not enough for implementing our IFormattedText interface. |
Does three.js have it's own rendering engine that can draw text using TrueType/Freetype fonts with proper subpixel rendering? |
If it does, it might be worth to create some kind of a wrapper, but currently calling JS code from WASM is very inconvenient. This is currently the only way of calling JS code from C#, which is basically an There is some existing glue code here (JS part here) which uses the internal call from an alternative mono wasm target implementation, which is basically an |
They are going through the font glyphs and turning them into path geometries and then feeding them to WebGL. If they can do that then they could have measured them. It looks like nothing more than an oversight that they didn't include measuring functions. (I'm not yet clear on what font format they're expecting but my assumption would be WOFF). re JS interop, again I would assume the endgame would be porting what we need from three.js to C# so that all the calculating code would be done in WASM and the only time you'd need to interop would be the final render into WebGL. But why not try a POC at least? |
@pmoorelegistek It seems that Mono WebAssembly SDK is providing libmono and an example C source file with the entry point. That means that we can link additional libraries to the resulting runtime mostly without issues. |
We can measure text etc but we can't apply kerning or any other glyph positioning. Everything else is possible. |
The problem is that it is likely to produce different results. Which will break the layout. |
It should not produce different results in size if the browser follows common standards. The only difference is the quality of rendered glyphs. |
Anyway if I'm understanding correctly the challenge is to make sure that text measurements in the layout pass match what the renderer actually produces. But this should be the case if the renderer and the measuring system are part of the same codebase. Thus, if you used HTML+CSS to render, and canvas The layout pass in C# would still need interop with JS to measure strings in either case, but some clever caching of string and font property combinations along with the fact that full layout passes don't happen terribly often should get you where you need to be. |
Also just an FYI, invoking JS from WASM does NOT require an |
The problem is that there are no text measurement APIs on JS side. At least there weren't when I've last checked.
|
Well, there's a lot more you can do in JS to get the text measurements you need.
Take a look at three.js's code for rendering text from TTF or WOFF: This could easily be expanded to measure rather than just render. |
We don't gain much from that. We already have the ability to generate svg data for a given string. This will still not produce pixel perfect results. I think we can work something out with my new text layout that produces GlyphRun objects under the hood. We then just transfer these GlyphRuns to the Javascript side and let it process there again. We can apply same font features etc. but have to rely on the browser's shaping capabilities to produce the same results. In reality this will not be an issue because every browser uses HarfBuzz as well. A lightweight version of this will just contain the characters and info about font properties. |
@Gillibald so you'd measure in C#, pass just the text and font info to the browser, and pray it measures the way you assumed it would? The only way you can guarantee agreement between the measurement and the rendering is for both to be done by the same code. And since you have to minimize the amount of data moving between C#/wasm and JS, that means the only viable solution is to do both measurement and rendering browser side. |
Rendering only differs on sub pixel level. Measures are defines by the data that a font defines. The only possible difference in measurement comes from different shaping. So for example our shaping engine selects a ligature for specified text but the browser doesn't. This will measure differently because we use one glyph but the browser would use two glyphs. If we would let the browser measure everything we would need to cross Javascript / Wasm interop two times. Also the amount of data would be huge. Because we would need to transfer measures of each glyph. |
In a perfect world maybe. Work with browsers much? :/
Cache measurements by font+size+style+string. |
Can't you use a JavaScript-based text rendering engine or something so that you can control what it does? (or a more general 2D rendering engine that also supports text like https://two.js.org/examples/) |
Uno Platform (https://platform.uno/) is rendering the WPF from Microsoft to WebAssembly. There should not that difficult to port the code to render Avalonia too ... Maybe, there could be a way to join efforts ... |
Uno does not render anything as Avalonia does. They use HTML elements. |
They also have a Skia backend, not sure it's generally available for Wasm yet, but it is the plan. |
related comment:
https://developercommunity.visualstudio.com/idea/378455/net-ui-standard.html also:
|
What about Ubuntu (Linux environment)? |
regarding Uno and Linux see here: https://platform.uno/uno-platform-for-linux/ |
I was referring Avalonia in Linux environment compiling into WebAssembly |
guess Avalonia could also get ideas from Uno, or maybe even use it as a backend or something? |
Just to be clear. Text rendering is no longer an issue. The "only" thing we need is a platform implementation for WASM that is setting up WebGL and exposes all input events. The threading implementation might also be tricky. |
May be we can learn from google flutter, skia should not be a problem! |
I don't know if it is of any help, but there is this: lume/glas: WebGL in WebAssembly with AssemblyScript |
Seems skia with p/invoke is possible now: |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Would it be possible to host Avalonia with WebAssembly and .NET in a browser?
Then we could write the same C# code and run it native in all browser and on all desktops.
The text was updated successfully, but these errors were encountered: