New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GL Context Lost - preventDefault #11435

Closed
leweaver opened this Issue Jun 2, 2017 · 10 comments

Comments

Projects
None yet
6 participants
@leweaver

leweaver commented Jun 2, 2017

Description of the problem

The updated WebVR 1.1 specification has provisions for multi-GPU systems, which rely on correct usage of the webglcontextlost and webglcontextrestored events, or, the page not handling the events at all.

  • note, that due to a documentation build issue, you may need to look at the source spec bikeshed file - search for 'context will be lost'.

Currently three.js handles the event webglcontextlost, calling event.preventDefault to inform the browser that it intends to handle the webglcontextrestored event, yet makes no attempt to rebuild the resources (nor handle that event). Further, resetGLState(), setDefaultGLState() etc should actually occur in a webglcontextrestored.

Until such a time as three.js can confidently handle the webglcontextrestored event (such as building on the method proposed in issue #5507) handling of context lost should be removed entirely - or at the very least, not make a call to event.preventDefault() in the event handler.

From three.js WebGLRenderer.js:538

	function onContextLost( event ) {
		// LW: Remove this until glcontextrestored is handled correctly
		event.preventDefault();

		// LW: Below here should actually be in glcontextrestored
		resetGLState();
		setDefaultGLState();

		properties.clear();
		objects.clear();

	}
Three.js version
  • Dev
  • r85
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • macOS
  • Linux
  • Android
  • iOS
Hardware Requirements (graphics card, VR Device, ...)

Multi GPU system (such as a laptop, or a machine with motherboard integrated graphics and a discrete adapter)
VR Headset plugged in to discrete GPU
Monitor plugged in to integrated motherboard graphics

@toji

This comment has been minimized.

Contributor

toji commented Jun 7, 2017

To expand on what @leweaver said: We've also determined that the next revision of WebVR (which should be the one that sticks around) will have forced context loss as a core concept of using WebGL with a VR device. Pull request here.

The TL;DR version is that contexts used with WebVR devices will need to have a compatibility bit set on them. You can do this two ways. First, with a context creation arg, like so:

let gl = glCanvas.getContext("webgl", { compatibleVrDevice: vrDevice });

This won't cause context loss, but may not be appropriate if you don't know ahead of time that the user will be using a specific VRDevice. The second method is a bit more disruptive:

let gl = glCanvas.getContext("webgl");

// Some time later...
gl.setCompatibleVrDevice(vrDevice).then(() => {
    // If the VRDevice is connected to a different GPU than the one
    // the WebGL context was created with this would have forced
    // a context loss. The promise only resolves when the context
    // has been restored. If the page doesn't handle it the promise
    // is rejected.
});

Obviously the context loss case won't be triggered every single time, and many devices (such as mobile) may never see a context loss. But devices with multiple GPUs (even laptops with an integrated/discreet pair) could hit this path frequently.

Ideally Three.js can provide some mechanisms for dealing with context loss and promote it as something that developers need to pay attention to, otherwise you'll get a lot of devs who test their content on a single-GPU system and say "It Works!" and then wonder why things fail on some systems when their content is released in the wild.

@mrdoob

This comment has been minimized.

Owner

mrdoob commented Jun 30, 2017

Okay. Basic support added. Works in most of the cases but a few things break when restored (sprites, lensflares, etc). I'll be fixing them over the next days.

@kenrussell

This comment has been minimized.

kenrussell commented Jun 30, 2017

This is great news!

@mrdoob

This comment has been minimized.

Owner

mrdoob commented Jul 19, 2017

Ok, after b317394, 5e661c2, 79c14c8 and f6392b4 this should now be working.

@mrdoob mrdoob closed this Jul 19, 2017

Repository owner deleted a comment from Icerion777 Jul 19, 2017

@makc

This comment has been minimized.

Contributor

makc commented Jul 19, 2017

@mrdoob let's say I have a cube map that is rendered once and then used somewhere; now if I subscribe to 'webglcontextrestored' on canvas - will I have all the resources ready in order to re-render the cube map? do I also need to render() the scene to handle needUpdate=true stuff 1st? give us tutorial :D

@mrdoob

This comment has been minimized.

Owner

mrdoob commented Jul 19, 2017

Good question. If you setup a jsfiddle I'll adapt it to make it work 😊

@makc

This comment has been minimized.

Contributor

makc commented Jul 19, 2017

@mrdoob

This comment has been minimized.

Owner

mrdoob commented Jul 19, 2017

@makc

Basically, the user will have to take care of some things:

renderer.domElement.addEventListener( 'webglcontextrestored', function () {

	cubeCamera.updateCubeMap( renderer, scene );

} );

https://jsfiddle.net/hfj7gm6t/4284/

@leweaver

This comment has been minimized.

leweaver commented Jul 25, 2017

Thanks @mrdoob - just tested this out and it is working great!

@mrdoob

This comment has been minimized.

Owner

mrdoob commented Jul 25, 2017

@leweaver 🙌

@vxna vxna referenced this issue Aug 14, 2017

Closed

Thanks #1

ofrohn added a commit to ofrohn/three.js that referenced this issue Jun 17, 2018

Repository owner deleted a comment from dirttech Dec 4, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment