-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Fix/webgpu crash pixel density #8476
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
base: dev-2.0
Are you sure you want to change the base?
Fix/webgpu crash pixel density #8476
Conversation
test/unit/webgpu/issue_repro.js
Outdated
|
|
||
| // If we reach here, no immediate crash occurred. | ||
| // Let's wait for the context to finish resetting to be sure everything is stable. | ||
| await new Promise(resolve => setTimeout(resolve, 100)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Timeouts in tests are fairly brittle, we can use expect(() => { ... }).not.toThrow() or something like that as an alternative.
test/unit/webgpu/issue_repro.js
Outdated
| myp5 = new p5(function(p) { | ||
| p.setup = async function() { | ||
| try { | ||
| await p.createCanvas(100, 100, 'webgpu'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use p.WEBGPU rather than the value of the constant?
test/unit/webgpu/issue_repro.js
Outdated
| await p.createCanvas(100, 100, 'webgpu'); | ||
|
|
||
| // This triggers an asynchronous _resetContext | ||
| p.setAttributes({ powerPreference: 'low-power' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% sure that we'll do something with this, can we try changing antialias as a more normal example?
test/unit/webgpu/issue_repro.js
Outdated
| @@ -0,0 +1,51 @@ | |||
| import p5 from '../../../src/app.js'; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A new file called issue_repro.js is not really readable for future contributors trying to understand the structure of our code and tests. Could this just be a test in the existing WebGPU renderer tests?
src/webgpu/p5.RendererWebGPU.js
Outdated
| } | ||
|
|
||
| _updateSize() { | ||
| if (!this.device) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, is this added just to methods that get called automatically when you reinitialize the context?
|
Thanks for working on this! Left a few comments, let me know what you think! |
|
Thanks for the review, @davepagurek Those points make total sense. I'll move the test into the main WebGPU suite and swap out the setTimeout for a cleaner expect().not.toThrow() assertion. I’ll also update the test to use p.WEBGPU and antialias as you suggested. I'll double-check the guard clause scoping and push the updates shortly! |
173936d to
c8206c2
Compare
Fixes #8456
Description
Fixes a crash when using the WebGPU renderer where calling pixelDensity() immediately after setAttributes() (or any other function that triggers an asynchronous context reset) would result in
TypeError: Cannot read properties of undefined (reading 'createTexture').The Issue
In p5.js 2.0, setAttributes() triggers an asynchronous reset of the rendering context via _resetContext(). Because core functions like pixelDensity() are synchronous, they can trigger a resize() (and subsequently _updateSize()) on a new renderer instance before its WebGPU device has been successfully initialized.
Changes
this.deviceis not yet defined. Since _initContext() calls these methods upon successful initialization, the state is eventually synchronized correctly once the device is ready.awaitthe new renderer'scontextReadypromise before replacing the existing renderer on the p5 instance. This ensures that the sketch's_rendererproperty always points to a valid, initialized renderer.Checklist