greggman/webgpu-dev-extension

Fix the issue of the UI not appearing when stopped in the Debugger

greggman opened this issue · 0 comments

I'm not sure what the real solution is but I can explain what I think the problem is

  1. The injected scripts need to run before the JavaScript on your page.

    Based on the manifest, when a page starts, gpu-content-script.js is injected based on
    settings in the manifest.json.

    That script needs to know which options to enable. In other words, it needs to know the
    user's extension settings. Unfortunately there is no way to communicate with an extension
    synchronously. If the communication is async, then the page may start WebGPU before the
    extension gets a chance to wrap the API so async solutions are out (1)

  2. It's using session storage to store the settings

    A way to work around the first problem is to use session storage. Session storage
    can be read synchronously so gpu-content-script.js reads it and then applies the
    correct options.

    The problem is, session storage can only be set from the page itself. So, the extension
    sends a message to the page, "read the session storage settings and send them back to me".
    If the page is paused in the debugger, this message is not responded to and the extension
    UI never starts. Even if it did start, it has the same issue to set the settings. It send
    a message to the page "store these settings" and if the page is paused in the debugger
    then the setting would not get set.

Solution idea 1: Find a different storage method

This storage method needs to be able to be read by the page synchronously at startup. It also needs to be able to be by the extension even when the page is paused in the debugger

Solution idea 2: Try to timeout the message

This idea is for the extension to send the message, "read settings" or "write settings", to the page and if there is no response, show the error "Page is unresponsive: Unpause it you're in DevTools"

Solution idea 3: Switch to a Devtools extension?

Not sure if that helps or not

Note

  1. One idea I had was, since requestAdapter is async, I could read the settings async there, based on those settings wrap the API, then return the adapter.

    The problem with this solution is the page might wrap WebGPU itself or include a library that wraps WebGPU. If so, that wrapping would happen before these scripts got a chance to wrap and then these script wouldn't work.

    A possible solution there is pre-wrap the WebGPU API, and then un-wrap it if nothing is used.

    // wrapping code
    const origFn = GPU.prototype.requestAdapter
    
    async function wrappedRequestAdapter(...args) {
       const settings = await getSettingsFromExtension(...);
       if (noWrappingNeeded(settings)) {
          GPU.prototype.requestAdapter = origFn;
       }
       return away origFn.call(this, ...args);
    };
    
    GPU.prototype.requestAdapter = wrappedRequestAdapter;

    You'd have to wrap the entire API and then restore it all if no wrapping is needed.

    The problem would be that if other code is wrapping the API then it will read
    GPU.prototype.requestAdapter and get back wrappedRequestAdapter before we get
    a chance to restore it. And, when we restore it we'll restore the wrong thing (origFn
    instead of the app's wrapper).

    We could try to make more minimal wrapper but basically, if the webgpu-dev-extension
    is turned on, even with all settings off, it would affect perf. What we want is that if
    everything is off there's absolutely no impact to having the extension enabled.