regl-scatterplot icon indicating copy to clipboard operation
regl-scatterplot copied to clipboard

(regl) context lost

Open oskbor opened this issue 1 year ago • 5 comments

Hi! I have seen that some of our users are experiencing (regl) context lost errors when they leave a page idle for a while (with a regl-scatterplot in it). From some cursory research it seems this can happen for a many reasons like the GPU being used by other tabs, too many contexts open across tabs, a laptop switching GPU when plugged in/out. Is it possible for regl-scatterplot to detect and recover from this error? Or can I recover from my application somehow?

best regards Oskar

oskbor avatar Jun 28 '24 07:06 oskbor

That's a tough issue as the application cannot control when the context is lost. It can happen any time. Weirdly I've never experienced it myself but you could try to catch the context loss error and re-instantiate the scatterplot. E.g.: https://stackoverflow.com/a/28170868

To catch a context loss event is easy. Just listen for the event on the renderer's canvas element as exemplified https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/contextlost_event#example

flekschas avatar Jun 28 '24 13:06 flekschas

In case someone is looking for a solution to handle regl context loss:

We couldn't make it work by adding an event listener to the canvas element directly:

const canvas = document.getElementById("canvas");
canvas.addEventListener("contextlost", (event) => {
  console.log(event);
});

Instead, we added the event listener to the 'regl' instance:

useEffect(
    function reglContextLostListener() {
      const regl = scatterPlot?.get("regl");
      const handleContextLost = () => {
        scatterPlot?.destroy();
        handleError("Context lost");
      };
      regl?.on("lost", handleContextLost);     
    },
    [scatterPlot, handleError]
  );

Unfortunately, we couldn't find a way to remove the 'regl' event listener.

Sagva avatar Aug 07 '24 09:08 Sagva

We couldn't make it work by adding an event listener to the canvas element directly

That's likely due to the fact that the canvas element you selected is the one for displaying the output and not the one for rendering.

You should be able to get the appropriate canvas as follows:

useEffect(() => {
  const canvas = scatterPlot?.get('renderer').canvas;
  const handleContextLost = () => {
    scatterPlot?.destroy();
    handleError("Context lost");
    registerEvent("Error encountered");
  }; 
  canvas.addEventHandler('contextlost', handleContextLost);
  return canvas.removeEventHandler('contextlost', handleContextLost);
}, [scatterPlot, handleError, registerEvent]);

flekschas avatar Aug 07 '24 21:08 flekschas

You should be able to get the appropriate canvas as follows:

This approach doesn't t work either, attached eventListener to const canvas = scatterPlot?.get('renderer').canvas; doesn't catch the event.

Sagva avatar Aug 08 '24 06:08 Sagva

Interesting! Maybe regl itself is catching the error before it bubbles up?

flekschas avatar Aug 08 '24 11:08 flekschas