Skip to content

Commit 3a7992c

Browse files
authored
Merge pull request #8476 from saurabh24thakur/fix/webgpu-crash-pixel-density
Fix/webgpu crash pixel density
2 parents 7d6153b + 007bd76 commit 3a7992c

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

src/webgpu/p5.RendererWebGPU.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ function rendererWebGPU(p5, fn) {
9393
this.finalCamera = new Camera(this);
9494
this.finalCamera._computeCameraDefaultSettings();
9595
this.finalCamera._setDefaultCamera();
96+
97+
this.depthFormat = 'depth24plus-stencil8';
98+
this.depthTexture = null;
99+
this.depthTextureView = null;
96100
}
97101

98102
async setupContext() {
@@ -133,7 +137,6 @@ function rendererWebGPU(p5, fn) {
133137
});
134138

135139
// TODO disablable stencil
136-
this.depthFormat = 'depth24plus-stencil8';
137140
this.mainFramebuffer = this.createFramebuffer({ _useCanvasFormat: true });
138141
this._updateSize();
139142
this._update();
@@ -190,6 +193,7 @@ function rendererWebGPU(p5, fn) {
190193
}
191194

192195
_updateSize() {
196+
if (!this.device || !this.depthFormat) return;
193197
if (this.depthTexture && this.depthTexture.destroy) {
194198
this.flushDraw();
195199
const textureToDestroy = this.depthTexture;
@@ -284,6 +288,7 @@ function rendererWebGPU(p5, fn) {
284288
}
285289

286290
clear(...args) {
291+
if (!this.device || !this.drawingContext) return;
287292
const _r = args[0] || 0;
288293
const _g = args[1] || 0;
289294
const _b = args[2] || 0;
@@ -350,6 +355,7 @@ function rendererWebGPU(p5, fn) {
350355
* occlude anything subsequently drawn.
351356
*/
352357
clearDepth(depth = 1) {
358+
if (!this.device || !this.depthTextureView) return;
353359
this._finishActiveRenderPass();
354360
const commandEncoder = this.device.createCommandEncoder();
355361

test/unit/webgpu/p5.RendererWebGPU.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ suite('WebGPU p5.RendererWebGPU', function() {
1616
});
1717

1818
beforeEach(async function() {
19-
await myp5.createCanvas(50, 50, 'webgpu');
19+
await myp5.createCanvas(50, 50, myp5.WEBGPU);
2020
});
2121

2222
afterEach(function() {
@@ -126,4 +126,41 @@ suite('WebGPU p5.RendererWebGPU', function() {
126126
}
127127
});
128128
});
129+
130+
suite('Stability', function() {
131+
test('pixelDensity() after setAttributes() should not crash', async function() {
132+
// This test simulates the issue where a synchronous call (pixelDensity)
133+
// happens before an asynchronous initialization (setAttributes -> _resetContext)
134+
// is complete.
135+
await new Promise((resolve, reject) => {
136+
try {
137+
myp5 = new p5(p => {
138+
p.setup = async function() {
139+
try {
140+
await p.createCanvas(100, 100, p.WEBGPU);
141+
142+
// This triggers an asynchronous _resetContext
143+
p.setAttributes({ antialias: true });
144+
145+
// This triggers a synchronous resize() -> _updateSize()
146+
// before the new renderer's device is ready.
147+
expect(() => {
148+
p.pixelDensity(1);
149+
}).not.toThrow();
150+
151+
resolve();
152+
} catch (err) {
153+
reject(err);
154+
}
155+
};
156+
});
157+
} catch (err) {
158+
reject(err);
159+
}
160+
});
161+
162+
// Verify stability after the async reset
163+
expect(myp5._renderer).to.exist;
164+
});
165+
});
129166
});

0 commit comments

Comments
 (0)