Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/webgpu/p5.RendererWebGPU.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ function rendererWebGPU(p5, fn) {
this.finalCamera = new Camera(this);
this.finalCamera._computeCameraDefaultSettings();
this.finalCamera._setDefaultCamera();

this.depthFormat = 'depth24plus-stencil8';
this.depthTexture = null;
this.depthTextureView = null;
}

async setupContext() {
Expand Down Expand Up @@ -133,7 +137,6 @@ function rendererWebGPU(p5, fn) {
});

// TODO disablable stencil
this.depthFormat = 'depth24plus-stencil8';
this.mainFramebuffer = this.createFramebuffer({ _useCanvasFormat: true });
this._updateSize();
this._update();
Expand Down Expand Up @@ -190,6 +193,7 @@ function rendererWebGPU(p5, fn) {
}

_updateSize() {
if (!this.device || !this.depthFormat) return;
if (this.depthTexture && this.depthTexture.destroy) {
this.flushDraw();
const textureToDestroy = this.depthTexture;
Expand Down Expand Up @@ -284,6 +288,7 @@ function rendererWebGPU(p5, fn) {
}

clear(...args) {
if (!this.device || !this.drawingContext) return;
const _r = args[0] || 0;
const _g = args[1] || 0;
const _b = args[2] || 0;
Expand Down Expand Up @@ -350,6 +355,7 @@ function rendererWebGPU(p5, fn) {
* occlude anything subsequently drawn.
*/
clearDepth(depth = 1) {
if (!this.device || !this.depthTextureView) return;
this._finishActiveRenderPass();
const commandEncoder = this.device.createCommandEncoder();

Expand Down
39 changes: 38 additions & 1 deletion test/unit/webgpu/p5.RendererWebGPU.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ suite('WebGPU p5.RendererWebGPU', function() {
});

beforeEach(async function() {
await myp5.createCanvas(50, 50, 'webgpu');
await myp5.createCanvas(50, 50, myp5.WEBGPU);
});

afterEach(function() {
Expand Down Expand Up @@ -126,4 +126,41 @@ suite('WebGPU p5.RendererWebGPU', function() {
}
});
});

suite('Stability', function() {
test('pixelDensity() after setAttributes() should not crash', async function() {
// This test simulates the issue where a synchronous call (pixelDensity)
// happens before an asynchronous initialization (setAttributes -> _resetContext)
// is complete.
await new Promise((resolve, reject) => {
try {
myp5 = new p5(p => {
p.setup = async function() {
try {
await p.createCanvas(100, 100, p.WEBGPU);

// This triggers an asynchronous _resetContext
p.setAttributes({ antialias: true });

// This triggers a synchronous resize() -> _updateSize()
// before the new renderer's device is ready.
expect(() => {
p.pixelDensity(1);
}).not.toThrow();

resolve();
} catch (err) {
reject(err);
}
};
});
} catch (err) {
reject(err);
}
});

// Verify stability after the async reset
expect(myp5._renderer).to.exist;
});
});
});