regl-scatterplot
regl-scatterplot copied to clipboard
(regl) context lost
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
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
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.
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]);
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.
Interesting! Maybe regl itself is catching the error before it bubbles up?