hi all, we’re experiencing some loss of WGL context when resizing window only on PC/Chrome/Edge. i tried to do a memory diff trace to see if there was a leak somewhere… nothing seems aparent.
i made a pg example replicating exactly what we’re doing but the pg does not seem to loose context but our internal app does. (unfortunately i cant post that publicly)
also attached is the warnings we’re getting when we loose ctx.
- are you telling the engine to not handle context loss? (obvious, just getting out of the way)
var engine = new BABYLON.Engine(canvas, true, {doNotHandleContextLost: true});
//or
engine.doNotHandleContextLost = true
- are you using offscreen canvas?
- is react managing your canvas element?
This happens due to screen resize as you are probably already really cause to the memory limit of your app.
First you should try to debounce the resize to be sure it does not happen as often.
Also I am wondering if you are not recreating resources vs resizing (delete → create) them ?
@sebavan hey now you are on to something i think! we do render at 2x res (using hw scaling) and yes we are at the limits. we just are working on a system where during any user interaction (including screen resize) we’re rendering at 1/2 the rez and only go to full rez when the scene is ‘idle’.
im a little confused as to what you mean by if we are re-creating assets. on a resize we simply scene.render(). we dont need to add/remove/delete any assets from the scene during this event.
any rendertarget texture used in post processes and such might need to be recreated for instance.
As long as you do not hook in resize to do special context management yourself, it should be good.
I one glfw/native webgpu demo i ran recently completely recreated all the frame buffers on resize to match the new size, do u know if chrome does that too? I was thinking it’d be better to just use the displays size instead of window
update: so we just implimented the above system where we only render at double rez when the scene is idle. GPU usage is almost 1/4th what it was before. Very promising technique but still needs some tweaking. Seems that we are loosing webgl context much less frequently now but it still happens here and there. The only thing we are doing when we hook into resize is calculate the FOV mode. so basically:
window.addEventListener('resize', () => this.onResize());
onResize() {
const [ renderWidth, renderHeight ] = this.state.renderWindow;
const fovMode = renderWidth > renderHeight
? Camera.FOVMODE_VERTICAL_FIXED
: Camera.FOVMODE_HORIZONTAL_FIXED;
scene.activeCamera.fovMode = fovMode
engine.resize();
sceneNeedRender = true; // this bool is checked in the renderloop and if true will render one frame
}
when we do loose WGL context, im getting these warnings.
1 Like
You should debounce the onResize call and not let it happen more than once per second I d guess ?
debouncing the resize worked like a charm… So one last dumb question. I want to clear the render buffer during the resize (we just want to see a solid color during the resize and nothing else). How do I do this. I cant seem to find anything in scene or engine.
better yet, if there is a way where the existing canvas wont resize even if the window is resizing that would be great. like if the existing canvas could just stay in the top left scaled to whatever the previous scale/aspect was until we issue a engine.resize() and scene.render() call.
There are no built-ins. I would suggest to not call scene.render the first frame after a resize but engine.clear instead ? or display an overlay div on top.