pixijs
pixijs copied to clipboard
Too many active WebGL context even after destroyed
Hi, recently I've migrated to Pixi V6 (from v4) in a ReactJS project and I've been seeing my Google Chrome browser log saying WARNING: Too many active WebGL contexts. Oldest context will be lost.
I'm aware that every browser has a limit of how many active WebGL context can be running at a time. That's why I'll destroy the unused one when they are not needed to make sure the total active WebGL context is within the limit.
Back then when I was integrating Pixi v4, I encountered similar issue but I managed to solve it by destroying the PIXI.Application when it's not needed. Now I've updated to Pixi v6 and this warning has came back again.
This is how I create PIXI.Application
const options = {
width: width,
height: height,
backgroundAlpha: transparent ? 0 : 1,
resolution: window.devicePixelRatio,
autoDensity: true
};
let app = new PIXI.Application(options);
app.stage.position.set(width * 0.5, height * 0.5);
app.renderer.plugins.interaction.autoPreventDefault = false;
app.renderer.view.style.touchAction = 'auto';
this.gameCanvas.appendChild(this.app.view);
and this is what I will do when component is going to unmount
this.gameCanvas.removeChild(app.view);
const options = {
children: true
}
app.destroy(true, options);
Does anyone know how can I solve this problem?
UPDATE: Tested on Firefox but somehow I didn't see this warning message from the console.
I have also noticed this with PIXI 6, and can also confirm that this seems to happen in Chrome but not Firefox.
A very similar issue I encountered back during PIXI 5: https://github.com/pixijs/pixijs/issues/5997
An updated playground based on the one from that issue: https://pixiplayground.com/#/edit/4UmnnyPSGRuUHbmAG2cDP
We should make sure a context loss is triggered when destroying and that a reference to the canvas isn't being held on. These might hinder disposing of the WebGL context.
That said, this is a very common issue and there are a number of ways to manage it:
- with React, I usually create the Application outside of React rendering. Instead of destroying, you can detach the view, stop rendering, clear the stage, destroy textures, and resize the renderer to 1x1. Doing this minimizes the memory and cpu overheard. Keeping a single app reference is the most reliable.
- alternatively, you could iframe your renderering and post message rendering changes. Removing the iframe would dispose of the context entirely.
I realized I was behind a few patch versions on the pixi 6 series. I updated to 6.5.9 and, to my immense relief, I no longer see this behavior in Chrome.
I am still seeing this behavior in 7.2.4 🙏
Try this
const disposePixiApp = (app: Application) => {
/**
* Remove stage correctly
* reference: https://github.com/pixijs/pixijs/issues/2233#issuecomment-192227185
*/
if ('gl' in app.renderer) {
(app.renderer.gl as WebGLRenderingContext)
.getExtension('WEBGL_lose_context')
?.loseContext();
}
};
const ReactApp = () => {
return (
<Stage
width={800}
height={600}
onUnmount={disposePixiApp} // <- use it here
>
{/* something awesome */}
</Stage>
);
};