Search Unity

Unity in worker using transferControlToOffscreen

Discussion in 'Web' started by UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582, Feb 18, 2019.

  1. UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    Joined:
    Jun 19, 2018
    Posts:
    23
    We using Unity webgl in our game. Freezing at start is very annoying So I decided to try a new feature Canvas.transferControlToOffscreen() to start Unity in a worker.

    I copied Framework (builded js code) and successfully compiled and instantiated module in a worker.
    Everything is fine and Module.asm._main() was called.
    But Engine crashes without any meaningful reason.


    Loading player data from data.unity3d
    Initialize engine version: 2018.3.5f1 (76b3e37670a4)
    PlatformGetStacktrace
    Could not initialize WebGL context. Failed starting Unity.
    at wasm-function[2306]:37
    at wasm-function[2291]:597
    at wasm-function[7951]:109
    at wasm-function[7912]:668
    at wasm-function[7901]:54
    at wasm-function[7881]:21
    at wasm-function[7826]:996
    (Filename: Line: 699)


    Is it possible to run Unity in a worker?
    I added Module.ENVIRONMENT = 'WORKER' but it didn`t help.
     
    xProvoker likes this.
  2. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    You ~might~ have some luck if you compile with the emscriptenArgs flag -s OFFSCREEN_CANVAS_SUPPORT=1. The only other issue I ran into was a mysterious undefined GLctxIsOnParentThread variable in the wasm.framework.unityweb file which didn't seem to mind being removed.

    I suspect it might not be this easy though.
     
  3. UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    Joined:
    Jun 19, 2018
    Posts:
    23
    Yep, it wasn`t.
     
  4. UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    Joined:
    Jun 19, 2018
    Posts:
    23
  5. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    Interesting.. how did you manage to get it working in the end? I was under the impression the browser offscreen canvas support was around for a little longer before Chrome 69 but I might be mistaken. I'd be curious how feasible it is to implement a fallback for older browsers as well.

    Nice job by the way!
     
  6. UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    Joined:
    Jun 19, 2018
    Posts:
    23
    The main feature you need is transferControlToOffscreen.
    You taking canvas from the DOM, call transferControlToOffscreen() and getting OffscreenCanvas instance (all in main thread)
    And here you get two things:
    1. Everything you draw on OffscreenCanvas will be mirrored to DOM`s canvas
    2. OffscreenCanvas is Transferable - can be transfer from main thread to the worker

    So you just need to start Unity instance in a worker with transfered offscreen canvas

    The main problem that Unity expects some properties like window, style, addEventListener... You`ll need to bypass all of them.

    It was easier for me because earlier I refused to use UnityLoader.js. I have my own 300 line`s script to load wasm code, it uses streamingCompilation by the way
     
  7. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    Neat, I'll give that a go. This should make it easier for us to handle our authentication flow during load rather than after WebGL has loaded, among other potential changes. A custom loader shouldn't be an issue for us.
     
  8. UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    Joined:
    Jun 19, 2018
    Posts:
    23
    Look at
    Module['locateFile']
    if you are using 2018.* version
     
  9. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    331
    Very interesting! Did putting Unity in a separate worker reduce the freezing? Kind of a bummer it's only on Chrome atm (although perhaps behind a flag in firefox).
     
    De-Panther likes this.
  10. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
  11. De-Panther

    De-Panther

    Joined:
    Dec 27, 2009
    Posts:
    589
    Do you think that Safari will also support it?
     
  12. UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    Joined:
    Jun 19, 2018
    Posts:
    23
    I tried with enabled flag - tab always crashes.
     
  13. UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    UDN_08a62c30-cdb1-4e59-bb48-acda29f9e582

    Joined:
    Jun 19, 2018
    Posts:
    23
    I`m sure about it, but the most important question "When?"
     
    De-Panther likes this.
  14. JJJohan

    JJJohan

    Joined:
    Mar 18, 2016
    Posts:
    214
    I managed to get it working with a slightly modified UnityLoader.js (mainly just changing the loadCode function to use JS Worker's importScripts function instead of loading things by importing a <script> element, and grabbing the eventhandler proxy logic from your own example.

    I wasn't aware that unfortunately it doesn't seem to support a WebGL 2 context yet which is a shame (even though I'm not really using any WebGL 2 specific features right now).

    I've attached an extremely minimal example that includes the index.html, an offscreencanvas.js file (the JS worker) and an unminified, slightly modified UnityLoader.js - keep in mind that since it is super minimal it doesn't actually pass events to/from the main thread, or more importantly handle regular load fallback if OffscreenCanvas isn't supported. It's more an example :).
     

    Attached Files: