mobile-sdk icon indicating copy to clipboard operation
mobile-sdk copied to clipboard

[New Platform] Compile Mobile SDK to the Web/Javascript via Emscripten

Open bugra9 opened this issue 3 years ago • 5 comments

Hi @mtehver, I ported this excellent project to the web. My motivation,

  • As @jaakla mentioned here(#66), I wanted to learn the limits of Emscripten/Webassembly.
  • I wanted to see a map with powerful and performant vector rendering on the web.
  • I'm imagining a map that will run on three platforms (Android, iOS, Web) with the same code. This might be possible with React Native if someone integrates JSI into mobile swig.

This implementation covers multiple projects so I'm writing to this issue instead of a pull request. Related projects;

  • I added function overloading support using parameter types to embind. https://github.com/emscripten-core/emscripten/pull/17445
  • I added emscripten support to mobile swig. (It's ugly, but it works fine. :)) https://github.com/CartoDB/mobile-swig/pull/3
  • I added emscripten support to this project. https://github.com/CartoDB/mobile-sdk/pull/509

Demo: https://mobile-sdk-web.netlify.app/ Example Usage: https://github.com/bugra9/mobile-sdk/blob/emscripten-support/scripts/emscripten-dev/main.js

In the demo application, the debug icon appears after 7 seconds. You can test live with it.

Tested;

  • Marker
  • Line
  • Text
  • BalloonPopup
  • MbTiles with 3D Polygon
  • NMLModel
  • RasterTileLayer/HTTPTileDataSource
  • MapEventListener, VectorTileEventListener

Known Issues;

  • ~NMLModel looks transparent.~
  • ~onMapClicked and onVectorTileClicked don't work. (Emscripten bug. Event is thrown to the listener only in the main thread.)~
  • Emscripten don't support streaming downloads so the application cannot cancel the request when it is not needed. (Emscripten issue. https://emscripten.org/docs/api_reference/fetch.html#streaming-downloads)
  • I want to download tiles in parallel for performance. To do this I set setTileThreadPoolSize to 20 in options but it caused performance drops as it says in the documentation. In my opinion, network operations should be able to work asynchronously.
  • Rendering/animation worked on MacOS 12 and on iOS 15.5 but tiles were not loaded. Safari log shows 'Failed to load resource: Worker load was blocked by Cross-Origin-Embedder-Policy'
  • Empty page on iOS 14.3. Could not find anything in the log. My guess is that WebAssembly is not supported on this device. So probably expected.

bugra9 avatar Jul 17 '22 20:07 bugra9

@bugra9 amazing! I tried your demo site on my mobile phone and I got a blank page. I ll try tomorrow on my computer

farfromrefug avatar Jul 17 '22 21:07 farfromrefug

@farfromrefug, I deployed very fast and didn't optimize for size. If your internet is slow, you may have to wait a little longer.

What is your browser name?

I tested it on Firefox Android and Chrome Android and it worked.

bugra9 avatar Jul 17 '22 21:07 bugra9

I waites quite a lot and still white page. I see the debug button but then nothing in the console. tried on system webview, bromite(chrome) and mull(Firefox)

farfromrefug avatar Jul 18 '22 05:07 farfromrefug

@bugra9 Very impressive! I did a basic Emscripten port of mobile-carto-libs 2-3 years ago just for testing but making full SDK port seemed way too much work :-).

I will take a closer look at the code later this week and will add detailed questions/comments. But at the high level it looks very good.

I did a quick test on different devices:

  • Worked perfectly on Chrome Windows and on Android 12.
  • Rendering/animation worked on MacOS 12 and on iOS 15.5 but tiles were not loaded. Safari log shows 'Failed to load resource: Worker load was blocked by Cross-Origin-Embedder-Policy'
  • Empty page on iOS 14.3. Could not find anything in the log. My guess is that WebAssembly is not supported on this device. So probably expected.

mtehver avatar Jul 19 '22 09:07 mtehver

Thank you. It was quite difficult for me, but the result was worth the effort. I learned a lot.

SharedArrayBuffer is required for thread support. For security reasons, it is necessary to add two headers to the response. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements

I added "Cross-Origin-Opener-Policy: same-origin" and "Cross-Origin-Embedder-Policy: require-corp" but I don't understand why Apple doesn't allow access to SharedArrayBuffer. I will investigate this.

bugra9 avatar Jul 24 '22 23:07 bugra9